<!DOCTYPE html>





<html class="theme-next gemini use-motion" lang="zh-CN">
<head>
  <meta charset="UTF-8">
<meta name="generator" content="Hexo 3.9.0">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
  <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png?v=7.3.0">
  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png?v=7.3.0">
  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png?v=7.3.0">
  <link rel="mask-icon" href="/images/logo.svg?v=7.3.0" color="#222">

<link rel="stylesheet" href="/css/main.css?v=7.3.0">


<link rel="stylesheet" href="/lib/font-awesome/css/font-awesome.min.css?v=4.7.0">


<script id="hexo-configurations">
  var NexT = window.NexT || {};
  var CONFIG = {
    root: '/',
    scheme: 'Gemini',
    version: '7.3.0',
    exturl: false,
    sidebar: {"position":"left","display":"post","offset":12,"onmobile":false},
    back2top: {"enable":true,"sidebar":false,"scrollpercent":false},
    save_scroll: false,
    copycode: {"enable":false,"show_result":false,"style":null},
    fancybox: false,
    mediumzoom: false,
    lazyload: false,
    pangu: false,
    algolia: {
      appID: '',
      apiKey: '',
      indexName: '',
      hits: {"per_page":10},
      labels: {"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}
    },
    localsearch: {"enable":true,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},
    path: 'search.xml',
    motion: {"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}},
    translation: {
      copy_button: '复制',
      copy_success: '复制成功',
      copy_failure: '复制失败'
    }
  };
</script>

  <meta name="description" content="欢迎你的到来！">
<meta property="og:type" content="website">
<meta property="og:title" content="淡退">
<meta property="og:url" content="http://yoursite.com/index.html">
<meta property="og:site_name" content="淡退">
<meta property="og:description" content="欢迎你的到来！">
<meta property="og:locale" content="zh-CN">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="淡退">
<meta name="twitter:description" content="欢迎你的到来！">
  <link rel="canonical" href="http://yoursite.com/">


<script id="page-configurations">
  // https://hexo.io/docs/variables.html
  CONFIG.page = {
    sidebar: "",
    isHome: true,
    isPost: false,
    isPage: false,
    isArchive: false
  };
</script>

  <title>淡退</title>
  








  <noscript>
  <style>
  .use-motion .motion-element,
  .use-motion .brand,
  .use-motion .menu-item,
  .sidebar-inner,
  .use-motion .post-block,
  .use-motion .pagination,
  .use-motion .comments,
  .use-motion .post-header,
  .use-motion .post-body,
  .use-motion .collection-title { opacity: initial; }

  .use-motion .logo,
  .use-motion .site-title,
  .use-motion .site-subtitle {
    opacity: initial;
    top: initial;
  }

  .use-motion .logo-line-before i { left: initial; }
  .use-motion .logo-line-after i { right: initial; }
  </style>
</noscript>

</head>

<body itemscope itemtype="http://schema.org/WebPage" lang="zh-CN">

  <div class="container sidebar-position-left">
    <div class="headband"></div>

    <header id="header" class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-wrapper">
  <div class="site-meta">

    <div class="custom-logo-site-title">
      <a href="/" class="brand" rel="start">
        <span class="logo-line-before"><i></i></span>
        <span class="site-title">淡退</span>
        <span class="logo-line-after"><i></i></span>
      </a>
    </div>
        <p class="site-subtitle">---脂肪肝患者</p>
      
  </div>

  <div class="site-nav-toggle">
    <button aria-label="切换导航栏">
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
    </button>
  </div>
</div>


<nav class="site-nav">
  
  <ul id="menu" class="menu">
      
      
      
        
        <li class="menu-item menu-item-home">
      
    

    <a href="/" rel="section"><i class="menu-item-icon fa fa-fw fa-home"></i> <br>首页</a>

  </li>
      
      
      
        
        <li class="menu-item menu-item-about">
      
    

    <a href="/about/" rel="section"><i class="menu-item-icon fa fa-fw fa-user"></i> <br>关于</a>

  </li>
      
      
      
        
        <li class="menu-item menu-item-tags">
      
    

    <a href="/tags/" rel="section"><i class="menu-item-icon fa fa-fw fa-tags"></i> <br>标签</a>

  </li>
      
      
      
        
        <li class="menu-item menu-item-categories">
      
    

    <a href="/categories/" rel="section"><i class="menu-item-icon fa fa-fw fa-th"></i> <br>分类</a>

  </li>
      
      
      
        
        <li class="menu-item menu-item-archives">
      
    

    <a href="/archives/" rel="section"><i class="menu-item-icon fa fa-fw fa-archive"></i> <br>归档</a>

  </li>
      <li class="menu-item menu-item-search">
        <a href="javascript:;" class="popup-trigger">
        
          <i class="menu-item-icon fa fa-search fa-fw"></i> <br>搜索</a>
      </li>
    
  </ul>

</nav>
  <div class="site-search">
    
  <div class="popup search-popup">
  <div class="search-header">
    <span class="search-icon">
      <i class="fa fa-search"></i>
    </span>
    <div class="search-input-wrapper">
      <input autocomplete="off"
             placeholder="搜索..." spellcheck="false"
             type="text" id="search-input">
    </div>
    <span class="popup-btn-close">
      <i class="fa fa-times-circle"></i>
    </span>
  </div>
  <div id="search-result"></div>
</div>


  </div>
</div>
    </header>

    


    <main id="main" class="main">
      <div class="main-inner">
        <div class="content-wrap">
            

          <div id="content" class="content page-home">
            
  <section id="posts" class="posts-expand">
      

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="http://yoursite.com/2019/12/06/2019/11/jenkins前端自动部署入门/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="淡退">
      <meta itemprop="description" content="欢迎你的到来！">
      <meta itemprop="image" content="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1565847089857&di=2bb546a711f57b819a4dbf3584c66392&imgtype=0&src=http%3A%2F%2Fhbimg.b0.upaiyun.com%2F458af12108c4da0f1cf4fe8e2713a458898e332b28196-jdjJ3j_fw658">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="淡退">
    </span>
      <header class="post-header">
        
          <i class="fa fa-thumb-tack"></i>
          <font color=7D26CD>置顶</font>
        

        
          <h1 class="post-title" itemprop="name headline">
              
              <a href="/2019/12/06/2019/11/jenkins前端自动部署入门/" class="post-title-link" itemprop="url">jenkins前端自动部署入门</a>
            
          </h1>
        

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              <span class="post-meta-item-text">发表于</span>

              
                
              

              <time title="创建时间：2019-12-06 23:10:17" itemprop="dateCreated datePublished" datetime="2019-12-06T23:10:17+08:00">2019-12-06</time>
            </span>
          
            

            
              <span class="post-meta-item">
                <span class="post-meta-item-icon">
                  <i class="fa fa-calendar-check-o"></i>
                </span>
                <span class="post-meta-item-text">更新于</span>
                <time title="修改时间：2019-12-08 21:06:26" itemprop="dateModified" datetime="2019-12-08T21:06:26+08:00">2019-12-08</time>
              </span>
            
          
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="fa fa-folder-o"></i>
              </span>
              <span class="post-meta-item-text">分类于</span>
              
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing"><a href="/categories/js/" itemprop="url" rel="index"><span itemprop="name">js</span></a></span>

                
                
              
            </span>
          

          

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
        <div class="post-gallery" itemscope itemtype="http://schema.org/ImageGallery">
            <div class="post-gallery-row">
              <img src="https://desk-fd.zol-img.com.cn/t_s1024x768c5/g5/M00/0C/02/ChMkJ13V9q6IOSp_AAPNPlvQOwwAAvV_QJYgfoAA81W947.jpg" itemprop="contentUrl">
            
          

          </div>
        </div>
          
            <a id="more"></a>

<h2 id="jenkins前端自动部署入门"><a href="#jenkins前端自动部署入门" class="headerlink" title="jenkins前端自动部署入门"></a>jenkins前端自动部署入门</h2><p>由于前端项目打包后是静态资源，不需要进程守护。一般地，前端项目使用jenkins来进行自动部署，包括打包、测试等一系列流程</p>
<p>由于 jenkins是基于java环境运行的，所以首先需要安装java环境</p>
<p>参考：<br><a href="https://jingyan.baidu.com/article/375c8e190c1f9525f2a22931.html" target="_blank" rel="noopener">https://jingyan.baidu.com/article/375c8e190c1f9525f2a22931.html</a></p>
<h4 id="下载"><a href="#下载" class="headerlink" title="下载"></a>下载</h4><p>1、下载地址：<a href="https://jenkins.io/download，" target="_blank" rel="noopener">https://jenkins.io/download，</a></p>
<p>下载最后war包, 下载完成后进入下载后的目录，在<code>cmd</code>中输入 <code>java -jar jenkins.war</code> 然后在页面输入<code>localhost:8080</code></p>
<h4 id="初始化"><a href="#初始化" class="headerlink" title="初始化"></a>初始化</h4><p>　　启动jenkins服务后，可以在8080端口访问到jenkins<br><img src="https://pic.xiaohuochai.site/blog/jenkins1.png" alt></p>
<p>然后在服务器的指定目录找到密码登录</p>
<p>/var/lib/jenkins/secrets/initialAdminPassword</p>
<p>按照默认配置安装插件 </p>
<p><img src="https://pic.xiaohuochai.site/blog/jenkins2.png" alt></p>
<p>等待插件安装完成</p>
<p><img src="https://pic.xiaohuochai.site/blog/jenkins3.png" alt></p>
<p>创建一个管理员账户，完成配置后，就可以登录 Jenkins 了</p>
<p><img src="https://pic.xiaohuochai.site/blog/jenkins4.png" alt></p>
<h4 id="安装插件"><a href="#安装插件" class="headerlink" title="安装插件"></a>安装插件</h4><p>下面来安装nodejs插件<br><img src="https://pic.xiaohuochai.site/blog/jenkins6.png" alt></p>
<p>可以看到，Jenkins提供了丰富的插件供开发者使用，找到需要的[NodeJS Plugin]，勾选后点击安装即可</p>
<p><img src="https://pic.xiaohuochai.site/blog/jenkins7.png" alt></p>
<blockquote>
<p>可能会出现网络不好或者被墙的情况，可以换一下域（百度一下）</p>
</blockquote>
<h4 id="配置任务"><a href="#配置任务" class="headerlink" title="配置任务"></a>配置任务</h4><ol>
<li>安装好github钩子以及nodejs插件后，接下来开始配置任务</li>
</ol>
<p>　　点击创建一个新任务，填写任务名称，构建的项目类型可根据实际情况进行选择，本次选择第一种即可<br>　　<br><img src="https://pic.xiaohuochai.site/blog/jenkins5.png" alt></p>
<ol start="2">
<li>配置基础信息</li>
</ol>
<p><img src="https://pic.xiaohuochai.site/blog/jenkins12.png" alt></p>
<ol start="3">
<li><p>往下拉，看到源码管理，点选Git，依然填写博客对应的Repo地址<br><img src="https://pic.xiaohuochai.site/blog/jenkins13.png" alt></p>
</li>
<li><p>继续往下拉，在构建触发器单击增加构建步骤，在弹出的下拉菜单中选择<code>Execute shell。勾选GitHub hook trigger for GITScm polling</code>。构建环境选择nodejs</p>
</li>
</ol>
<p><img src="https://pic.xiaohuochai.site/blog/jenkins14.png" alt></p>
<ol start="5">
<li>构建过程<br>一般地，构建过程，输入如下 <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">npm install &amp;&amp;</span><br><span class="line">npm run build</span><br></pre></td></tr></table></figure>

</li>
</ol>
<h3 id="问题处理："><a href="#问题处理：" class="headerlink" title="问题处理："></a>问题处理：</h3><ol>
<li><p>假如证书有问题的话会报错：<br><img src="https://img2018.cnblogs.com/blog/1406304/201905/1406304-20190527105223189-1051377169.png" alt><br>可以点击：  <a href="https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json" target="_blank" rel="noopener">https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json</a></p>
<p>滑动到最后，配置修改地址，将https改成http，</p>
</li>
</ol>
<p><a href="http://updates.jenkins.io/update-center.json" target="_blank" rel="noopener">http://updates.jenkins.io/update-center.json</a></p>
<p>或者</p>
<p><a href="https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json" target="_blank" rel="noopener">https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json</a></p>
<p>然后点击submit-&gt;checknow</p>
<ol start="2">
<li>插件管理页面提示：There were errors <code>checking the update sites:IOException:Unable to tunnel through proxy.Proxy returins &quot;HTTP/1.1 400&quot;</code><br><img src="https://img2018.cnblogs.com/blog/1406304/201905/1406304-20190524095823763-636781851.png" alt><br>解决办法和第一个是一样的。</li>
</ol>
<p>参考文档：</p>
<ul>
<li><a href="https://blog.csdn.net/lykio_881210/article/details/88557728" target="_blank" rel="noopener">Jenkins+GitHub集成接口测试环境部署</a></li>
<li><a href="https://www.cnblogs.com/grey-wolf/p/8716662.html" target="_blank" rel="noopener">jenkins实战（一）：war安装及插件安装</a></li>
<li><a href="https://www.cnblogs.com/imyalost/p/8677345.html" target="_blank" rel="noopener">jenkins简单安装及配置（Windows环境）</a></li>
<li><a href="https://blog.csdn.net/GISuuser/article/details/100121237" target="_blank" rel="noopener">Jenkins安装与插件安装连接超时问题</a></li>
<li><a href="https://blog.csdn.net/u011922006/article/details/88187060" target="_blank" rel="noopener">jenkins+github集成自动化测试环境搭建（1）-jenkins和github安装</a></li>
</ul>

          
        
      
    </div>

    
    
    
      <footer class="post-footer">
          <div class="post-eof"></div>
        
      </footer>
  </div>
  
  
  
  </article>

    
      

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="http://yoursite.com/2019/11/22/2019/11/Decorator装饰器 学习笔记/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="淡退">
      <meta itemprop="description" content="欢迎你的到来！">
      <meta itemprop="image" content="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1565847089857&di=2bb546a711f57b819a4dbf3584c66392&imgtype=0&src=http%3A%2F%2Fhbimg.b0.upaiyun.com%2F458af12108c4da0f1cf4fe8e2713a458898e332b28196-jdjJ3j_fw658">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="淡退">
    </span>
      <header class="post-header">
        
          <i class="fa fa-thumb-tack"></i>
          <font color=7D26CD>置顶</font>
        

        
          <h1 class="post-title" itemprop="name headline">
              
              <a href="/2019/11/22/2019/11/Decorator装饰器 学习笔记/" class="post-title-link" itemprop="url">Decorator装饰器 学习笔记</a>
            
          </h1>
        

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              <span class="post-meta-item-text">发表于</span>

              
                
              

              <time title="创建时间：2019-11-22 23:10:17" itemprop="dateCreated datePublished" datetime="2019-11-22T23:10:17+08:00">2019-11-22</time>
            </span>
          
            

            
              <span class="post-meta-item">
                <span class="post-meta-item-icon">
                  <i class="fa fa-calendar-check-o"></i>
                </span>
                <span class="post-meta-item-text">更新于</span>
                <time title="修改时间：2019-11-30 22:35:40" itemprop="dateModified" datetime="2019-11-30T22:35:40+08:00">2019-11-30</time>
              </span>
            
          
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="fa fa-folder-o"></i>
              </span>
              <span class="post-meta-item-text">分类于</span>
              
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing"><a href="/categories/js/" itemprop="url" rel="index"><span itemprop="name">js</span></a></span>

                
                
              
            </span>
          

          

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
        <div class="post-gallery" itemscope itemtype="http://schema.org/ImageGallery">
            <div class="post-gallery-row">
              <img src="https://desk-fd.zol-img.com.cn/t_s1024x768c5/g5/M00/0C/02/ChMkJ13V9q6IOSp_AAPNPlvQOwwAAvV_QJYgfoAA81W947.jpg" itemprop="contentUrl">
            
          

          </div>
        </div>
          
            <h2 id="装饰器分类"><a href="#装饰器分类" class="headerlink" title="装饰器分类"></a>装饰器分类</h2><p>Decorator装饰器是一种函数，写成@ + 函数名。它可以放在类和类方法的定义前面。</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">@frozen </span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Foo</span> </span>&#123;</span><br><span class="line">  @configurable(<span class="literal">false</span>)</span><br><span class="line">  @enumerable(<span class="literal">true</span>)</span><br><span class="line">  method() &#123;&#125;</span><br><span class="line"></span><br><span class="line">  @throttle(<span class="number">500</span>)</span><br><span class="line">  expensiveMethod() &#123;&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>上面代码一共使用了四个装饰器，一个用在类本身，另外三个用在类方法。所以个人理解：<br>装饰器分为<strong>类装饰器</strong>和<strong>类属性</strong>装饰器</p>
<h3 id="类装饰器"><a href="#类装饰器" class="headerlink" title="类装饰器"></a>类装饰器</h3><p>顾名思义是用来装饰整个类</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">@testable</span><br><span class="line">class MyTestableClass &#123;</span><br><span class="line">  // ...</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">function testable(target) &#123;</span><br><span class="line">  target.isTestable = true;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">MyTestableClass.isTestable // true</span><br></pre></td></tr></table></figure>

<p>上面代码中，<code>@testable</code>就是一个装饰器。它修改了<code>MyTestableClass</code>这个类的行为，为它加上了静态属性<code>isTestable</code>。<code>testable</code>函数的参数<code>target</code>是<code>MyTestableClass</code>类本身。</p>
<p>基本上，装饰器的行为就是下面这样。</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">@decorator</span><br><span class="line">class A &#123;&#125;</span><br><span class="line"></span><br><span class="line">// 等同于</span><br><span class="line"></span><br><span class="line">class A &#123;&#125;</span><br><span class="line">A = decorator(A) || A;</span><br></pre></td></tr></table></figure>

<p>也就是说，装饰器是一个对类进行处理的函数。装饰器函数的第一个参数，就是所要装饰的目标类。</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">function testable(target) &#123;</span><br><span class="line">  // ...</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><code>testable</code>函数的参数<code>target</code>，就是会被装饰的类。</p>
<p>如果觉得一个参数不够用，可以在装饰器外面再封装一层函数。</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">function testable(isTestable) &#123;</span><br><span class="line">  return function(target) &#123;</span><br><span class="line">    target.isTestable = isTestable;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">@testable(true)</span><br><span class="line">class MyTestableClass &#123;&#125;</span><br><span class="line">MyTestableClass.isTestable // true</span><br><span class="line"></span><br><span class="line">@testable(false)</span><br><span class="line">class MyClass &#123;&#125;</span><br><span class="line">MyClass.isTestable // false</span><br></pre></td></tr></table></figure>

<p>装饰器testable可以接受参数，这就等于可以修改装饰器的行为。</p>
<blockquote>
<p>注意，装饰器对类的行为的改变，是代码编译时发生的，而不是在运行时。这意味着，装饰器能在编译阶段运行代码。也就是说，装饰器本质就是编译时执行的函数。</p>
</blockquote>
<h3 id="类属性装饰器"><a href="#类属性装饰器" class="headerlink" title="类属性装饰器"></a>类属性装饰器</h3><p>装饰器不仅可以装饰类，还可以装饰类的属性</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">class Person &#123;</span><br><span class="line">  @readonly</span><br><span class="line">  age=18;</span><br><span class="line">  @readonly</span><br><span class="line">  name() &#123; return `$&#123;this.first&#125; $&#123;this.last&#125;` &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>装饰器readonly用来装饰“类”的name方法和age属性。</p>
<p>实现readonly装饰器</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">function readonly(target, name, descriptor)&#123;</span><br><span class="line">  // descriptor对象原来的值如下</span><br><span class="line">  // &#123;</span><br><span class="line">  //   value: specifiedFunction, //对象属性的默认值，默认值为undefined</span><br><span class="line">  //   enumerable: false,//对象属性是否可通过for-in循环，flase为不可循环，默认值为true</span><br><span class="line">  //   configurable: true,//能否使用delete、能否需改属性特性、或能否修改访问器属性、，false为不可重新定义，默认值为true</span><br><span class="line">  //   writable: true,//对象属性是否可修改,flase为不可修改，默认值为true</span><br><span class="line">  // &#125;;</span><br><span class="line">  descriptor.writable = false;</span><br><span class="line">  return descriptor;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">readonly(Person.prototype, &apos;name&apos;, descriptor);</span><br><span class="line">// 类似于</span><br><span class="line">Object.defineProperty(Person.prototype, &apos;name&apos;, descriptor);</span><br></pre></td></tr></table></figure>

<p>类属性装饰器参数：</p>
<ul>
<li>第一个参数是类的<strong>原型对象</strong>，上例是<code>Person.prototype</code>，装饰器的本意是要“装饰”类的实例，但是这个时候实例还没生成，所以只能去装饰原型（这不同于类的装饰，那种情况时<code>target</code>参数指的是类本身）；</li>
<li>第二个参数是所要装饰的属性名，</li>
<li>第三个参数是该属性的描述对象。</li>
</ul>
<p>上面代码说明，装饰器（readonly）会修改属性的描述对象（descriptor），然后被修改的描述对象再用来定义属性。</p>
<h3 id="装饰器执行顺序"><a href="#装饰器执行顺序" class="headerlink" title="装饰器执行顺序"></a>装饰器执行顺序</h3><p>如果同一个方法有多个装饰器，会像剥洋葱一样，先从外到内进入，然后由内向外执行。</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">dec</span>(<span class="params">id</span>)</span>&#123;</span><br><span class="line">  <span class="built_in">console</span>.log(<span class="string">'evaluated'</span>, id);</span><br><span class="line">  <span class="keyword">return</span> <span class="function">(<span class="params">target, property, descriptor</span>) =&gt;</span> <span class="built_in">console</span>.log(<span class="string">'executed'</span>, id);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Example</span> </span>&#123;</span><br><span class="line">    @dec(<span class="number">1</span>)</span><br><span class="line">    @dec1(<span class="number">2</span>)</span><br><span class="line">    method()&#123;&#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// evaluated 1</span></span><br><span class="line"><span class="comment">// evaluated 2</span></span><br><span class="line"><span class="comment">// executed 2</span></span><br><span class="line"><span class="comment">// executed 1</span></span><br></pre></td></tr></table></figure>

<p>外层装饰器@dec(1)先进入，但是内层装饰器@dec(2)先执行。</p>
<h3 id="练习"><a href="#练习" class="headerlink" title="练习"></a>练习</h3><h4 id="练习1-调用这个类的所有方法的时候-都要输出日志"><a href="#练习1-调用这个类的所有方法的时候-都要输出日志" class="headerlink" title="练习1 调用这个类的所有方法的时候  都要输出日志"></a>练习1 调用这个类的所有方法的时候  都要输出日志</h4><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">function log(terget)&#123;</span><br><span class="line">    const desc = Object.getOwnPropertyDescriptors(terget.prototype);</span><br><span class="line">    </span><br><span class="line">    for (const key of Object.key(desc) ) &#123;</span><br><span class="line">        if(key === &apos;contstructor&apos;) &#123;</span><br><span class="line">            continue;</span><br><span class="line">        &#125;</span><br><span class="line">        </span><br><span class="line">        const func = desc[key].value;</span><br><span class="line">        if(typeof func === &apos;function&apos;)&#123;</span><br><span class="line">            Object.defineProperty(terget.prototype,key,&#123;</span><br><span class="line">                value(...args)&#123;</span><br><span class="line">                    console.log(&apos;before&apos;+key);</span><br><span class="line">                    const ret = func.apply(this,args);</span><br><span class="line">                    console.log(&apos;after&apos;+key);</span><br><span class="line">                    </span><br><span class="line">                    return ret;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;)</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line">@log</span><br><span class="line">class Numberic()&#123;</span><br><span class="line">    PI = 3.14</span><br><span class="line">    </span><br><span class="line">    add(...nums)&#123;</span><br><span class="line">        return nums.reduce((p,n) =&gt; (p+n),0)</span><br><span class="line">        </span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h4 id="练习2-对一个类的方法进行参数的验证，同时设置一个类的属性只能是只读。"><a href="#练习2-对一个类的方法进行参数的验证，同时设置一个类的属性只能是只读。" class="headerlink" title="练习2 对一个类的方法进行参数的验证，同时设置一个类的属性只能是只读。"></a>练习2 对一个类的方法进行参数的验证，同时设置一个类的属性只能是只读。</h4><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line">function readOnly(terget,name,descriptor)&#123;</span><br><span class="line">    descriptor.writable = false;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">function validate(terget,name,descriptor)&#123;</span><br><span class="line">    const func = descriptor.value;</span><br><span class="line">    descriptor.value = function(...args)&#123;</span><br><span class="line">        for(let num of args)&#123;</span><br><span class="line">            if(typeOf num !== &apos;number&apos;)&#123;</span><br><span class="line">                return new Error(`$&#123;num&#125; is not a number `)</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        </span><br><span class="line">        return func.apply(...args);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">class Numberic()&#123;</span><br><span class="line">    @readOnly</span><br><span class="line">    PI = 3.14</span><br><span class="line">    </span><br><span class="line">    @validate</span><br><span class="line">    add(...nums)&#123;</span><br><span class="line">        return nums.reduce((p,n) =&gt; (p+n),0)</span><br><span class="line">        </span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>


          
        
      
    </div>

    
    
    
      <footer class="post-footer">
          <div class="post-eof"></div>
        
      </footer>
  </div>
  
  
  
  </article>

    
      

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="http://yoursite.com/2019/11/20/2019/11/vuex全家桶总结/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="淡退">
      <meta itemprop="description" content="欢迎你的到来！">
      <meta itemprop="image" content="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1565847089857&di=2bb546a711f57b819a4dbf3584c66392&imgtype=0&src=http%3A%2F%2Fhbimg.b0.upaiyun.com%2F458af12108c4da0f1cf4fe8e2713a458898e332b28196-jdjJ3j_fw658">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="淡退">
    </span>
      <header class="post-header">
        
          <i class="fa fa-thumb-tack"></i>
          <font color=7D26CD>置顶</font>
        

        
          <h1 class="post-title" itemprop="name headline">
              
              <a href="/2019/11/20/2019/11/vuex全家桶总结/" class="post-title-link" itemprop="url">vuex全家桶总结</a>
            
          </h1>
        

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              <span class="post-meta-item-text">发表于</span>

              
                
              

              <time title="创建时间：2019-11-20 22:10:17" itemprop="dateCreated datePublished" datetime="2019-11-20T22:10:17+08:00">2019-11-20</time>
            </span>
          
            

            
              <span class="post-meta-item">
                <span class="post-meta-item-icon">
                  <i class="fa fa-calendar-check-o"></i>
                </span>
                <span class="post-meta-item-text">更新于</span>
                <time title="修改时间：2019-12-08 21:06:45" itemprop="dateModified" datetime="2019-12-08T21:06:45+08:00">2019-12-08</time>
              </span>
            
          
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="fa fa-folder-o"></i>
              </span>
              <span class="post-meta-item-text">分类于</span>
              
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing"><a href="/categories/vue/" itemprop="url" rel="index"><span itemprop="name">vue</span></a></span>

                
                
              
            </span>
          

          

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
        <div class="post-gallery" itemscope itemtype="http://schema.org/ImageGallery">
            <div class="post-gallery-row">
              <img src="https://desk-fd.zol-img.com.cn/t_s1440x900c5/g5/M00/0C/00/ChMkJ13VHGeIQbMvAAZiH-yBkAsAAvVdQCGfhkABmI3388.jpg" itemprop="contentUrl">
            
          

          </div>
        </div>
          
            <a id="more"></a>
<h3 id="vuex全家桶总结"><a href="#vuex全家桶总结" class="headerlink" title="vuex全家桶总结"></a>vuex全家桶总结</h3><h4 id="Vue脚手架引入store"><a href="#Vue脚手架引入store" class="headerlink" title="Vue脚手架引入store"></a>Vue脚手架引入store</h4><ol>
<li>利用npm包管理工具，进行安装 vuex。在控制命令行中输入下边的命令就可以了。<br>npm install vuex –save<br>要注意的是这里一定要加上 –save，因为你这个包我们在生产环境中是要使用的。</li>
<li>一个store文件夹，并在文件夹下新建store.js文件，文件中引入我们的vue和vuex。<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> Vue <span class="keyword">from</span> <span class="string">'vue'</span>;</span><br><span class="line"><span class="keyword">import</span> Vuex <span class="keyword">from</span> <span class="string">'vuex'</span>;</span><br></pre></td></tr></table></figure>

</li>
</ol>
<p>3、使用我们vuex，引入之后用Vue.use进行引用。<br><code>ue.use(Vuex)</code><br>通过这三步的操作，vuex就算引用成功了，接下来我们就可以尽情的玩耍了。</p>
<p>4、在main.js 中引入新建的vuex文件<br><code>mport store from &#39;./store/store&#39;</code></p>
<p>5、再然后 , 在实例化 Vue对象时加入 store 对象 :</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">new</span> Vue(&#123;</span><br><span class="line"> el: <span class="string">'#app'</span>,</span><br><span class="line"> router,</span><br><span class="line"> store,</span><br><span class="line"> components: &#123; App &#125;,</span><br><span class="line"> template: <span class="string">'&lt;App/&gt;'</span></span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>

<h4 id="基本结构介绍"><a href="#基本结构介绍" class="headerlink" title="基本结构介绍"></a>基本结构介绍</h4><ol>
<li>State</li>
</ol>
<ul>
<li>单一状态树，保存项目状态唯一数据源</li>
<li>通过 this.$store.state 直接访问</li>
<li>mapState 辅助函数</li>
</ul>
<ol start="2">
<li>Getter</li>
</ol>
<ul>
<li>定义 getter 方法</li>
<li>暴露出 store.getters 对象供访问</li>
<li>mapGetters 辅助函数</li>
</ul>
<ol start="3">
<li>Mutation</li>
</ol>
<ul>
<li>更改 store 数据</li>
<li>定义 matations 方法，通过 this.$store.commit() 调用</li>
<li>Mutation 必须是同步函数</li>
<li>mapMutations 辅助函数</li>
</ul>
<ol start="4">
<li>Action</li>
</ol>
<ul>
<li>通过调用 mutation 函数实现更新状态，但不能直接更新状态</li>
<li>可以包含异步操作</li>
<li>通过 this.$store.dispatch() 调用</li>
<li>结合 Promise 使用，实现组合 action</li>
<li>mapActions 辅助函数</li>
</ul>
<ol start="5">
<li>Module</li>
</ol>
<ul>
<li>模块化状态，对每个模块添加命名空间</li>
<li>通过辅助函数调用，调用getter,mutation,action方法前添加命名空间</li>
</ul>
<p>参考文章</p>
<p><a href="https://blog.csdn.net/ywl570717586/article/details/80136455" target="_blank" rel="noopener">非常全面的vuex—-mutation和action的基本使用方法</a></p>
<p><a href="https://segmentfault.com/a/1190000015782272" target="_blank" rel="noopener">VueJS中学习使用Vuex详解</a></p>

          
        
      
    </div>

    
    
    
      <footer class="post-footer">
          <div class="post-eof"></div>
        
      </footer>
  </div>
  
  
  
  </article>

    
      

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="http://yoursite.com/2019/11/17/2019/11/vue和react的css的模块化/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="淡退">
      <meta itemprop="description" content="欢迎你的到来！">
      <meta itemprop="image" content="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1565847089857&di=2bb546a711f57b819a4dbf3584c66392&imgtype=0&src=http%3A%2F%2Fhbimg.b0.upaiyun.com%2F458af12108c4da0f1cf4fe8e2713a458898e332b28196-jdjJ3j_fw658">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="淡退">
    </span>
      <header class="post-header">
        
          <i class="fa fa-thumb-tack"></i>
          <font color=7D26CD>置顶</font>
        

        
          <h1 class="post-title" itemprop="name headline">
              
              <a href="/2019/11/17/2019/11/vue和react的css的模块化/" class="post-title-link" itemprop="url">vue和react的css的模块化</a>
            
          </h1>
        

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              <span class="post-meta-item-text">发表于</span>

              
                
              

              <time title="创建时间：2019-11-17 22:10:17" itemprop="dateCreated datePublished" datetime="2019-11-17T22:10:17+08:00">2019-11-17</time>
            </span>
          
            

            
              <span class="post-meta-item">
                <span class="post-meta-item-icon">
                  <i class="fa fa-calendar-check-o"></i>
                </span>
                <span class="post-meta-item-text">更新于</span>
                <time title="修改时间：2019-12-08 21:06:41" itemprop="dateModified" datetime="2019-12-08T21:06:41+08:00">2019-12-08</time>
              </span>
            
          
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="fa fa-folder-o"></i>
              </span>
              <span class="post-meta-item-text">分类于</span>
              
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing"><a href="/categories/vue/" itemprop="url" rel="index"><span itemprop="name">vue</span></a></span>

                
                
              
            </span>
          

          

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
        <div class="post-gallery" itemscope itemtype="http://schema.org/ImageGallery">
            <div class="post-gallery-row">
              <img src="https://desk-fd.zol-img.com.cn/t_s1440x900c5/g5/M00/0C/00/ChMkJ13VHGeIQbMvAAZiH-yBkAsAAvVdQCGfhkABmI3388.jpg" itemprop="contentUrl">
            
          

          </div>
        </div>
          
            <a id="more"></a>
<h3 id="vue中的css-模块化"><a href="#vue中的css-模块化" class="headerlink" title="vue中的css 模块化"></a>vue中的css 模块化</h3><h4 id="style-scope"><a href="#style-scope" class="headerlink" title="style scope"></a>style scope</h4><p>在vue的组件中如果<style scope></style>加上了scope，表明该标签里面写的样式都只作用在当前的页面，加上scope后，会自动添加一个唯一的属性，来确定该css样式作用的范围。<br>比如：</p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">style</span> <span class="attr">scoped</span>&gt;</span></span><br><span class="line">.example &#123;</span><br><span class="line">  color: red;</span><br><span class="line">&#125;</span><br><span class="line"><span class="tag">&lt;/<span class="name">style</span>&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;<span class="name">template</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">"example"</span>&gt;</span>hi<span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">template</span>&gt;</span></span><br></pre></td></tr></table></figure>

<p>编译渲染后的结果为：</p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">style</span>&gt;</span></span><br><span class="line">.example[data-v-f3f3eg9] &#123;</span><br><span class="line">  color: red;</span><br><span class="line">&#125;</span><br><span class="line"><span class="tag">&lt;/<span class="name">style</span>&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;<span class="name">template</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">"example"</span> <span class="attr">data-v-f3f3eg9</span>&gt;</span>hi<span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">template</span>&gt;</span></span><br></pre></td></tr></table></figure>

<p>当我们要编写全局样式的时候，或者要覆盖掉当前组件的样式的时候，不添加scope就可以做到。</p>
<blockquote>
<p>在一个 .vue 文件中可以写多个style 来做到样式的区分开。</p>
</blockquote>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">style</span>&gt;</span></span><br><span class="line">/* global styles */</span><br><span class="line"><span class="tag">&lt;/<span class="name">style</span>&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;<span class="name">style</span> <span class="attr">scoped</span>&gt;</span></span><br><span class="line">/* local styles */</span><br><span class="line"><span class="tag">&lt;/<span class="name">style</span>&gt;</span></span><br></pre></td></tr></table></figure>

<h4 id="在vue中使用css-modules"><a href="#在vue中使用css-modules" class="headerlink" title="在vue中使用css modules"></a>在vue中使用css modules</h4><p>在vue中使用css modules 只需要将scope 换成module <code>&lt;style module&gt;&lt;/style&gt;</code>，同时在css-loader中需要配置</p>
<p>css-loader关于CSS modules的默认配置如下</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">&#123;</span><br><span class="line">  modules: true,</span><br><span class="line">  importLoaders: 1,</span><br><span class="line">  localIdentName: &apos;[hash:base64]&apos;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>可以使用vue-loader的cssModules选项为css-loader进行自定义的配置</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">module: &#123;</span><br><span class="line">  rules: [</span><br><span class="line">    &#123;</span><br><span class="line">      test: &apos;\.vue$&apos;,</span><br><span class="line">      loader: &apos;vue-loader&apos;,</span><br><span class="line">      options: &#123;</span><br><span class="line">        cssModules: &#123;</span><br><span class="line">          localIdentName: &apos;[path][name]---[local]---[hash:base64:5]&apos;,</span><br><span class="line">          camelCase: true</span><br><span class="line">        &#125;</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">  ]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>参考文章：<br><a href="https://www.cnblogs.com/xiaohuochai/p/8537959.html" target="_blank" rel="noopener">在vue中使用css modules替代scroped</a></p>

          
        
      
    </div>

    
    
    
      <footer class="post-footer">
          <div class="post-eof"></div>
        
      </footer>
  </div>
  
  
  
  </article>

    
      

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="http://yoursite.com/2019/11/16/2019/11/React hookes/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="淡退">
      <meta itemprop="description" content="欢迎你的到来！">
      <meta itemprop="image" content="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1565847089857&di=2bb546a711f57b819a4dbf3584c66392&imgtype=0&src=http%3A%2F%2Fhbimg.b0.upaiyun.com%2F458af12108c4da0f1cf4fe8e2713a458898e332b28196-jdjJ3j_fw658">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="淡退">
    </span>
      <header class="post-header">
        
          <i class="fa fa-thumb-tack"></i>
          <font color=7D26CD>置顶</font>
        

        
          <h1 class="post-title" itemprop="name headline">
              
              <a href="/2019/11/16/2019/11/React hookes/" class="post-title-link" itemprop="url">React hookes 学习笔记</a>
            
          </h1>
        

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              <span class="post-meta-item-text">发表于</span>

              
                
              

              <time title="创建时间：2019-11-16 22:10:17" itemprop="dateCreated datePublished" datetime="2019-11-16T22:10:17+08:00">2019-11-16</time>
            </span>
          
            

            
              <span class="post-meta-item">
                <span class="post-meta-item-icon">
                  <i class="fa fa-calendar-check-o"></i>
                </span>
                <span class="post-meta-item-text">更新于</span>
                <time title="修改时间：2019-12-08 21:06:35" itemprop="dateModified" datetime="2019-12-08T21:06:35+08:00">2019-12-08</time>
              </span>
            
          
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="fa fa-folder-o"></i>
              </span>
              <span class="post-meta-item-text">分类于</span>
              
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing"><a href="/categories/react/" itemprop="url" rel="index"><span itemprop="name">react</span></a></span>

                
                
              
            </span>
          

          

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
        <div class="post-gallery" itemscope itemtype="http://schema.org/ImageGallery">
            <div class="post-gallery-row">
              <img src="https://desk-fd.zol-img.com.cn/t_s1440x900c5/g5/M00/0C/00/ChMkJ13VHGeIQbMvAAZiH-yBkAsAAvVdQCGfhkABmI3388.jpg" itemprop="contentUrl">
            
          

          </div>
        </div>
          
            <a id="more"></a>
<h2 id="React-hookes"><a href="#React-hookes" class="headerlink" title="React hookes"></a>React hookes</h2><h3 id="基本要求："><a href="#基本要求：" class="headerlink" title="基本要求："></a>基本要求：</h3><ol>
<li>只能在函数式组件中进行书写</li>
<li>只能在顶层调用Hooks。不要在循环，条件或嵌套函数中调用Hook。比如在if/eles 中就不能进行书写。</li>
</ol>
<h3 id="方法："><a href="#方法：" class="headerlink" title="方法："></a>方法：</h3><h4 id="useState-保存组件状态"><a href="#useState-保存组件状态" class="headerlink" title="useState 保存组件状态"></a>useState 保存组件状态</h4><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"> <span class="keyword">import</span> &#123; useState &#125; <span class="keyword">from</span> <span class="string">'react'</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">Example</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">const</span> [count, setCount] = useState(<span class="number">0</span>);</span><br><span class="line">  <span class="comment">//const [age, setAge] = useState(42);</span></span><br><span class="line">  <span class="comment">//const [fruit, setFruit] = useState('banana');</span></span><br><span class="line">  <span class="comment">//const [todos, setTodos] = useState([&#123; text: 'Learn Hooks' &#125;]);</span></span><br><span class="line"></span><br><span class="line">  <span class="keyword">return</span> (</span><br><span class="line">    &lt;div&gt;</span><br><span class="line">      &lt;p&gt;You clicked &#123;count&#125; times&lt;<span class="regexp">/p&gt;</span></span><br><span class="line"><span class="regexp">      &lt;button onClick=&#123;() =&gt; setCount(count + 1)&#125;&gt;</span></span><br><span class="line"><span class="regexp">        Click me</span></span><br><span class="line"><span class="regexp">      &lt;/</span>button&gt;</span><br><span class="line">    &lt;<span class="regexp">/div&gt;</span></span><br><span class="line"><span class="regexp">  );</span></span><br><span class="line"><span class="regexp">&#125;</span></span><br></pre></td></tr></table></figure>

<ul>
<li>useState的参数就是以前state的初始值。</li>
<li>useState返回的值中第一个参数是以前的state,第二个参数是setState,不过以前我们只有一个state,现在可以自由命名，更直观了，比如上面的age和setAge，fruit和setFruit</li>
</ul>
<blockquote>
<p>值得注意的是 useState 不帮助你处理状态，相较于 setState 非覆盖式更新状态，useState 覆盖式更新状态，需要开发者自己处理逻辑。</p>
</blockquote>
<p>参考下面的代码：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> React <span class="keyword">from</span> <span class="string">"react"</span>;</span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">App</span> <span class="keyword">extends</span> <span class="title">React</span>.<span class="title">Component</span> </span>&#123;</span><br><span class="line">  <span class="keyword">constructor</span>(props) &#123;</span><br><span class="line">    <span class="keyword">super</span>(props);</span><br><span class="line">    <span class="keyword">this</span>.state = &#123;</span><br><span class="line">      count: <span class="number">0</span>,</span><br><span class="line">      name: <span class="string">"alife"</span></span><br><span class="line">    &#125;;</span><br><span class="line">  &#125;</span><br><span class="line">  render() &#123;</span><br><span class="line">    <span class="keyword">const</span> &#123; count &#125; = <span class="keyword">this</span>.state;</span><br><span class="line">    <span class="keyword">return</span> (</span><br><span class="line">      &lt;div&gt;</span><br><span class="line">        Count: &#123;count&#125;</span><br><span class="line">        &lt;button onClick=&#123;() =&gt; <span class="keyword">this</span>.setState(&#123; <span class="attr">count</span>: count + <span class="number">1</span> &#125;)&#125;&gt;+&lt;/button&gt;</span><br><span class="line">        &lt;button onClick=&#123;() =&gt; <span class="keyword">this</span>.setState(&#123; <span class="attr">count</span>: count - <span class="number">1</span> &#125;)&#125;&gt;-&lt;/button&gt;</span><br><span class="line">      &lt;<span class="regexp">/div&gt;</span></span><br><span class="line"><span class="regexp">    );</span></span><br><span class="line"><span class="regexp">  &#125;</span></span><br><span class="line"><span class="regexp">&#125;</span></span><br></pre></td></tr></table></figure>

<p>使用useState后</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> React, &#123; useState &#125; <span class="keyword">from</span> <span class="string">"react"</span>;</span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">App</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">const</span> [obj, setObject] = useState(&#123;</span><br><span class="line">    count: <span class="number">0</span>,</span><br><span class="line">    name: <span class="string">"alife"</span></span><br><span class="line">  &#125;);</span><br><span class="line">  <span class="keyword">return</span> (</span><br><span class="line">    &lt;div className=<span class="string">"App"</span>&gt;</span><br><span class="line">      Count: &#123;obj.count&#125;</span><br><span class="line">      &lt;button onClick=&#123;() =&gt; setObject(&#123; ...obj, <span class="attr">count</span>: obj.count + <span class="number">1</span> &#125;)&#125;&gt;+&lt;/button&gt;</span><br><span class="line">      &lt;button onClick=&#123;() =&gt; setObject(&#123; ...obj, <span class="attr">count</span>: obj.count - <span class="number">1</span> &#125;)&#125;&gt;-&lt;/button&gt;</span><br><span class="line">    &lt;<span class="regexp">/div&gt;</span></span><br><span class="line"><span class="regexp">  );</span></span><br><span class="line"><span class="regexp">&#125;</span></span><br></pre></td></tr></table></figure>

<p>从useState的例子可以看出，我们在setObject中<code>{...obj,count:obj.count+1}</code>对其进行了一个全覆盖，相较于 setState是 非覆盖式更新状态，useState覆盖式更新状态，需要我们处理逻辑。</p>
<h4 id="useEffect-处理副作用"><a href="#useEffect-处理副作用" class="headerlink" title="useEffect 处理副作用"></a>useEffect 处理副作用</h4><p>为了直观的看出useEffect的用法和作用，我们将下面的例子改成用hooks的例子。</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> React, &#123; Component &#125; <span class="keyword">from</span> <span class="string">"react"</span>;</span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">App</span> <span class="keyword">extends</span> <span class="title">Component</span> </span>&#123;</span><br><span class="line">  state = &#123;</span><br><span class="line">    count: <span class="number">1</span></span><br><span class="line">  &#125;;</span><br><span class="line">  componentDidMount() &#123;</span><br><span class="line">    <span class="keyword">const</span> &#123; count &#125; = <span class="keyword">this</span>.state;</span><br><span class="line">    <span class="built_in">document</span>.title = <span class="string">"componentDidMount"</span> + count;</span><br><span class="line">    <span class="keyword">this</span>.timer = setInterval(<span class="function"><span class="params">()</span> =&gt;</span> &#123;</span><br><span class="line">      <span class="keyword">this</span>.setState(<span class="function">(<span class="params">&#123; count &#125;</span>) =&gt;</span> (&#123;</span><br><span class="line">        count: count + <span class="number">1</span></span><br><span class="line">      &#125;));</span><br><span class="line">    &#125;, <span class="number">1000</span>);</span><br><span class="line">  &#125;</span><br><span class="line">  componentDidUpdate() &#123;</span><br><span class="line">    <span class="keyword">const</span> &#123; count &#125; = <span class="keyword">this</span>.state;</span><br><span class="line">    <span class="built_in">document</span>.title = <span class="string">"componentDidMount"</span> + count;</span><br><span class="line">  &#125;</span><br><span class="line">  componentWillUnmount() &#123;</span><br><span class="line">    <span class="built_in">document</span>.title = <span class="string">"componentWillUnmount"</span>;</span><br><span class="line">    clearInterval(<span class="keyword">this</span>.timer);</span><br><span class="line">  &#125;</span><br><span class="line">  render() &#123;</span><br><span class="line">    <span class="keyword">const</span> &#123; count &#125; = <span class="keyword">this</span>.state;</span><br><span class="line">    <span class="keyword">return</span> (</span><br><span class="line">      &lt;div&gt;</span><br><span class="line">        Count:&#123;count&#125;</span><br><span class="line">        &lt;button onClick=&#123;() =&gt; clearInterval(<span class="keyword">this</span>.timer)&#125;&gt;clear&lt;<span class="regexp">/button&gt;</span></span><br><span class="line"><span class="regexp">      &lt;/</span>div&gt;</span><br><span class="line">    );</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>在例子中，组件每隔一秒更新组件状态，并且每次触发更新都会触发 document.title 的更新(副作用)，而在组件卸载时修改 document.title（类似于清除）</p>
<p>从例子中可以看到，一些重复的功能开发者需要在 componentDidMount 和 componentDidUpdate 重复编写，而如果使用 useEffect 则完全不一样</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> React, &#123; useState, useEffect &#125; <span class="keyword">from</span> <span class="string">"react"</span>;</span><br><span class="line"><span class="keyword">let</span> timer = <span class="literal">null</span>;</span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">App</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">const</span> [count, setCount] = useState(<span class="number">0</span>);</span><br><span class="line">  useEffect(<span class="function"><span class="params">()</span> =&gt;</span> &#123;</span><br><span class="line">    <span class="built_in">document</span>.title = <span class="string">"componentDidMount"</span> + count;</span><br><span class="line">  &#125;,[count]);</span><br><span class="line"> </span><br><span class="line">  useEffect(<span class="function"><span class="params">()</span> =&gt;</span> &#123;</span><br><span class="line">    timer = setInterval(<span class="function"><span class="params">()</span> =&gt;</span> &#123;</span><br><span class="line">      setCount(<span class="function"><span class="params">prevCount</span> =&gt;</span> prevCount + <span class="number">1</span>);</span><br><span class="line">    &#125;, <span class="number">1000</span>);</span><br><span class="line">    <span class="keyword">return</span> <span class="function"><span class="params">()</span> =&gt;</span> &#123;</span><br><span class="line">      <span class="built_in">document</span>.title = <span class="string">"componentWillUnmount"</span>;</span><br><span class="line">      clearInterval(timer);</span><br><span class="line">    &#125;;</span><br><span class="line">  &#125;, []);</span><br><span class="line">  <span class="keyword">return</span> (</span><br><span class="line">    &lt;div&gt;</span><br><span class="line">      Count: &#123;count&#125;</span><br><span class="line">      &lt;button onClick=&#123;() =&gt; clearInterval(timer)&#125;&gt;clear&lt;<span class="regexp">/button&gt;</span></span><br><span class="line"><span class="regexp">    &lt;/</span>div&gt;</span><br><span class="line">  );</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>将上面的例子用使用 useEffect 重写了上面的例子，useEffect 第一个参数传递函数，可以用来做一些副作用比如异步请求，修改外部参数等行为，而第二个参数是个数组，如果数组中的值改变才会触发 useEffect 第一个参数中的函数。返回值(如果有)则在组件销毁或者调用函数前调用。</p>
<ol>
<li>比如第一个 useEffect 中，理解起来就是一旦 count 值发生改变，则修改 documen.title 值</li>
<li>而第二个 useEffect 中数组没有传值，代表不监听任何参数变化，即只有在组件初始化或销毁的时候才会触发，用来代替 componentDidMount 和 componentWillUnmount</li>
</ol>
<p>参考文章：</p>
<p><a href="https://lindongzhou.com/article/learn-react-hooks" target="_blank" rel="noopener">十个案例学会 React Hooks</a></p>
<p><a href="https://zhuanlan.zhihu.com/p/48264713" target="_blank" rel="noopener">对React Hooks的一些思考</a></p>

          
        
      
    </div>

    
    
    
      <footer class="post-footer">
          <div class="post-eof"></div>
        
      </footer>
  </div>
  
  
  
  </article>

    
      

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="http://yoursite.com/2019/11/16/2019/11/关于一个项目多个环境的问题理解和解决办法/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="淡退">
      <meta itemprop="description" content="欢迎你的到来！">
      <meta itemprop="image" content="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1565847089857&di=2bb546a711f57b819a4dbf3584c66392&imgtype=0&src=http%3A%2F%2Fhbimg.b0.upaiyun.com%2F458af12108c4da0f1cf4fe8e2713a458898e332b28196-jdjJ3j_fw658">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="淡退">
    </span>
      <header class="post-header">
        
          <i class="fa fa-thumb-tack"></i>
          <font color=7D26CD>置顶</font>
        

        
          <h1 class="post-title" itemprop="name headline">
              
              <a href="/2019/11/16/2019/11/关于一个项目多个环境的问题理解和解决办法/" class="post-title-link" itemprop="url">关于一个项目多个环境的问题理解和解决办法</a>
            
          </h1>
        

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              <span class="post-meta-item-text">发表于</span>

              
                
              

              <time title="创建时间：2019-11-16 21:10:17" itemprop="dateCreated datePublished" datetime="2019-11-16T21:10:17+08:00">2019-11-16</time>
            </span>
          
            

            
              <span class="post-meta-item">
                <span class="post-meta-item-icon">
                  <i class="fa fa-calendar-check-o"></i>
                </span>
                <span class="post-meta-item-text">更新于</span>
                <time title="修改时间：2019-12-08 21:06:13" itemprop="dateModified" datetime="2019-12-08T21:06:13+08:00">2019-12-08</time>
              </span>
            
          
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="fa fa-folder-o"></i>
              </span>
              <span class="post-meta-item-text">分类于</span>
              
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing"><a href="/categories/react/" itemprop="url" rel="index"><span itemprop="name">react</span></a></span>

                
                
              
            </span>
          

          

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
        <div class="post-gallery" itemscope itemtype="http://schema.org/ImageGallery">
            <div class="post-gallery-row">
              <img src="https://desk-fd.zol-img.com.cn/t_s1440x900c5/g5/M00/0C/00/ChMkJ13VHGeIQbMvAAZiH-yBkAsAAvVdQCGfhkABmI3388.jpg" itemprop="contentUrl">
            
          

          </div>
        </div>
          
            <a id="more"></a>
<p>问题：由于项目有多个环境（uat,dev,stg1,stg2）,现在的需求是更具不同的环境，要控制页面上一个按钮的显示和隐藏。</p>
<p>问题分析和处理：<br>本地通过在yarn dev 命令里面通过传入不同的参数，然后页面通过js获取到不同环境的参数： 比如在开发环境中:</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">&quot;scripts&quot;: &#123;</span><br><span class="line">    &quot;start&quot;: &quot;cross-env BASE_PATH=/ PLATFORM_VERSION=OP CLIENT_ID=localhost BPM_HOST=http://256.000.00.127:8170 API_HOST=http://256.000.00.127:8080 WEBSOCKET_HOST=ws:/256.000.00.127:8120 SRC_WEBSOCKET_URL=http://256.000.00.127:8500 node --max_old_space_size=4196 scripts/start.js&quot;,</span><br><span class="line">    &quot;dev&quot;: &quot;cross-env BASE_PATH=/ PLATFORM_VERSION=SAAS CLIENT_ID=gjoy-front-dev BPM_HOST=http://256.000.00.127:8170 API_HOST=http://256.000.00.127:8080 WEBSOCKET_HOST=http://256.000.00.127:8120 SRC_WEBSOCKET_URL=http://256.000.00.127:8500 node --max_old_space_size=8196 scripts/start.js&quot;,</span><br><span class="line">    &quot;build&quot;: &quot;npm run lint:fix &amp;&amp; cross-env BASE_PATH=/ WEBSOCKET_HOST=BUILD_WEBSOCKET_HOST BPM_HOST=BUILD_BPM_HOST CLIENT_ID=BUILD_CLIENT_ID API_HOST=BUILD_API_HOST GENERATE_SOURCEMAP=false node --max_old_space_size=4196 scripts/build.js&quot;,</span><br><span class="line">  &#125;,</span><br></pre></td></tr></table></figure>

<p>脚本涵义：<br>cross-env 运行跨平台设置和使用环境变量的脚本，（npm i –save-dev cross-env 安装使用）<br>dev、 build分别表示开发环境和线上环境<br>CLIENT_ID： 对应的值就是gjoy-front-dev<br>BPM_HOST: 对应的值为<a href="http://192.168.16.172:8170" target="_blank" rel="noopener">http://192.168.16.172:8170</a><br>总之： 等号前面就是参数的名字，后面就是参数的值。<br>在页面上就可以通过： process.env.xxx 来获取对应参数的值</p>
<ol>
<li>最简单的解决方式： 在不同的环境中 设置不同的环境变量，然后在jenkins构建的时候 不同的环境执行不同的命令就可以了。<br>比如：<br>uat环境构建的时候 ： 设置CLIENT_ID为project_name_uat<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">build:uat: &quot;npm run lint:fix &amp;&amp; cross-env CLIENT_ID=project_name_uat  node --max_old_space_size=4196 scripts/build.js&quot;</span><br></pre></td></tr></table></figure>

</li>
</ol>
<p>dev环境构建的时候 ： 设置CLIENT_ID为project_name_dev</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">build:dev: &quot;npm run lint:fix &amp;&amp; cross-env CLIENT_ID=project_name_uat  node --max_old_space_size=4196 scripts/build.js&quot;</span><br></pre></td></tr></table></figure>

<p>stg环境构建的时候 ： 设置CLIENT_ID为project_name_stg</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">build:stg: &quot;npm run lint:fix &amp;&amp; cross-env CLIENT_ID=project_name_uat  node --max_old_space_size=4196 scripts/build.js&quot;</span><br></pre></td></tr></table></figure>

<p>这种方式：就是要在package.json中的scirpt中要写不同环境的不同命令。</p>
<p>但是在jenkins中写死了构建的时候调用的时候 <code>yarn build</code></p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&quot;build&quot;: &quot;npm run lint:fix &amp;&amp; cross-env BASE_PATH=/ WEBSOCKET_HOST=BUILD_WEBSOCKET_HOST BPM_HOST=BUILD_BPM_HOST CLIENT_ID=BUILD_CLIENT_ID API_HOST=BUILD_API_HOST GENERATE_SOURCEMAP=false node --max_old_space_size=4196 scripts/build.js&quot;,</span><br></pre></td></tr></table></figure>

<p>这个命令，且他们不想在修改构建命令中指令。所以另外在构建的时候需要在服务器中跑sh脚本 将构建完成的代码中使用到这个环境变量的地方，批量替换了。</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line">cd /opt/gjoy/apps/hces-front</span><br><span class="line">#git reset --hard</span><br><span class="line">git pull</span><br><span class="line">export PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=1 #macos/linux</span><br><span class="line">#rm -rf ./node_modules</span><br><span class="line">#rm -rf ./yarn.lock</span><br><span class="line">#安装依赖 </span><br><span class="line">#yarn add choerodon-ui --registry=http://nexus.saas.hand-china.com/content/groups/hzero-npm-group/ -W -flag</span><br><span class="line">yarn bootstrap</span><br><span class="line">#编译子模块</span><br><span class="line">lerna run transpile</span><br><span class="line">#打包dll </span><br><span class="line">yarn build:dll</span><br><span class="line"># 构建</span><br><span class="line">yarn build</span><br><span class="line">cd /usr/share/nginx/html/gjoy/</span><br><span class="line">rm -rf dist</span><br><span class="line">cp -r /opt/gjoy/apps/hces-front/dist .</span><br><span class="line">./setup.sh</span><br></pre></td></tr></table></figure>

<p>setup.sh </p>

          
        
      
    </div>

    
    
    
      <footer class="post-footer">
          <div class="post-eof"></div>
        
      </footer>
  </div>
  
  
  
  </article>

    
      

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="http://yoursite.com/2019/11/14/2019/11/Promise、Generator、Reflect、Map学习笔记/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="淡退">
      <meta itemprop="description" content="欢迎你的到来！">
      <meta itemprop="image" content="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1565847089857&di=2bb546a711f57b819a4dbf3584c66392&imgtype=0&src=http%3A%2F%2Fhbimg.b0.upaiyun.com%2F458af12108c4da0f1cf4fe8e2713a458898e332b28196-jdjJ3j_fw658">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="淡退">
    </span>
      <header class="post-header">
        
          <i class="fa fa-thumb-tack"></i>
          <font color=7D26CD>置顶</font>
        

        
          <h1 class="post-title" itemprop="name headline">
              
              <a href="/2019/11/14/2019/11/Promise、Generator、Reflect、Map学习笔记/" class="post-title-link" itemprop="url">Promise、Generator、Reflect、Map学习笔记</a>
            
          </h1>
        

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              <span class="post-meta-item-text">发表于</span>

              
                
              

              <time title="创建时间：2019-11-14 23:10:17" itemprop="dateCreated datePublished" datetime="2019-11-14T23:10:17+08:00">2019-11-14</time>
            </span>
          
            

            
              <span class="post-meta-item">
                <span class="post-meta-item-icon">
                  <i class="fa fa-calendar-check-o"></i>
                </span>
                <span class="post-meta-item-text">更新于</span>
                <time title="修改时间：2019-12-08 21:06:30" itemprop="dateModified" datetime="2019-12-08T21:06:30+08:00">2019-12-08</time>
              </span>
            
          
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="fa fa-folder-o"></i>
              </span>
              <span class="post-meta-item-text">分类于</span>
              
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing"><a href="/categories/js/" itemprop="url" rel="index"><span itemprop="name">js</span></a></span>

                
                
              
            </span>
          

          

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
        <div class="post-gallery" itemscope itemtype="http://schema.org/ImageGallery">
            <div class="post-gallery-row">
              <img src="https://desk-fd.zol-img.com.cn/t_s1440x900c5/g5/M00/0C/00/ChMkJ13VHGeIQbMvAAZiH-yBkAsAAvVdQCGfhkABmI3388.jpg" itemprop="contentUrl">
            
          

          </div>
        </div>
          
            <a id="more"></a>
<h2 id="11-13-学习总结和笔记"><a href="#11-13-学习总结和笔记" class="headerlink" title="11-13 学习总结和笔记"></a>11-13 学习总结和笔记</h2><h3 id="了解"><a href="#了解" class="headerlink" title="了解"></a>了解</h3><ol>
<li><p>Promise。</p>
</li>
<li><p>Generator、Reflect、Map。</p>
<!--more-->
<h1 id="Promise、Generator、Reflect、Map学习笔记"><a href="#Promise、Generator、Reflect、Map学习笔记" class="headerlink" title="Promise、Generator、Reflect、Map学习笔记"></a>Promise、Generator、Reflect、Map学习笔记</h1></li>
</ol>
<h2 id="Promise"><a href="#Promise" class="headerlink" title="Promise"></a>Promise</h2><p>Promise的出现是为了解决回调地狱的，使用Promise，我们就可以利用then进行「链式回调」</p>
<p>构建Promise</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//构建Promise</span></span><br><span class="line"><span class="keyword">var</span> promise = <span class="keyword">new</span> <span class="built_in">Promise</span>(<span class="function"><span class="keyword">function</span> (<span class="params">resolve, reject</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (<span class="comment">/* 异步操作成功 */</span>) &#123;</span><br><span class="line">        resolve(data);</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        <span class="comment">/* 异步操作失败 */</span></span><br><span class="line">        reject(error);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>

<p>类似构建对象，使用new来构建一个Promise。Promise接受一个「函数」作为参数，该函数的两个参数分别是resolve和reject。这两个函数就是就是「回调函数」，由JavaScript引擎提供。</p>
<p>Promise实例生成以后，可以用then方法指定resolved状态和reject状态的回调函数。</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//promise.then(onFulfilled, onRejected);</span></span><br><span class="line"></span><br><span class="line">promise.then(<span class="function"><span class="keyword">function</span>(<span class="params">data</span>) </span>&#123;</span><br><span class="line">  <span class="comment">// do something when success</span></span><br><span class="line">&#125;, <span class="function"><span class="keyword">function</span>(<span class="params">error</span>) </span>&#123;</span><br><span class="line">  <span class="comment">// do something when failure</span></span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>

<p>then方法会返回一个Promise。它有两个参数，分别为Promise从pending变为fulfilled和rejected时的回调函数（第二个参数非必选）。这两个函数都接受Promise对象传出的值作为参数。</p>
<h3 id="catch"><a href="#catch" class="headerlink" title=".catch()"></a>.catch()</h3><p>该方法是.then(undefined, onRejected)的别名，用于指定发生错误时的回调函数。</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">promise.then(<span class="function"><span class="keyword">function</span>(<span class="params">data</span>) </span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">'success'</span>);</span><br><span class="line">&#125;).catch(<span class="function"><span class="keyword">function</span>(<span class="params">error</span>) </span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">'error'</span>, error);</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"><span class="comment">/*******等同于*******/</span></span><br><span class="line">promise.then(<span class="function"><span class="keyword">function</span>(<span class="params">data</span>) </span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">'success'</span>);</span><br><span class="line">&#125;).then(<span class="literal">undefined</span>, <span class="function"><span class="keyword">function</span>(<span class="params">error</span>) </span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">'error'</span>, error);</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>

<p><code>promise</code>对象的错误，会一直向后传递，直到被捕获。即错误总会被下一个catch所捕获。then方法指定的回调函数，若抛出错误，也会被下一个<code>catch</code>捕获。<code>catch</code>中也能抛错，则需要后面的<code>catch</code>来捕获。</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">sendRequest(<span class="string">'test.html'</span>).then(<span class="function"><span class="keyword">function</span>(<span class="params">data1</span>) </span>&#123;</span><br><span class="line">    <span class="comment">//do something</span></span><br><span class="line">&#125;).then(<span class="function"><span class="keyword">function</span> (<span class="params">data2</span>) </span>&#123;</span><br><span class="line">    <span class="comment">//do something</span></span><br><span class="line">&#125;).catch(<span class="function"><span class="keyword">function</span> (<span class="params">error</span>) </span>&#123;</span><br><span class="line">    <span class="comment">//处理前面三个Promise产生的错误</span></span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>

<p><code>promise</code>一旦<code>resolve</code>了再抛错，也不会变为<code>rejected</code>，就不会被<code>catch</code>了。</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> promise = <span class="keyword">new</span> <span class="built_in">Promise</span>(<span class="function"><span class="keyword">function</span>(<span class="params">resolve, reject</span>) </span>&#123;</span><br><span class="line">  resolve();</span><br><span class="line">  <span class="keyword">throw</span> <span class="string">'error'</span>;</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">promise.catch(<span class="function"><span class="keyword">function</span>(<span class="params">e</span>) </span>&#123;</span><br><span class="line">   <span class="built_in">console</span>.log(e);      <span class="comment">//This is never called</span></span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>

<blockquote>
<p>如果没有使用catch方法指定处理错误的回调函数，Promise对象抛出的错误不会传递到外层代码，即不会有任何反应</p>
</blockquote>
<h3 id="all"><a href="#all" class="headerlink" title=".all()"></a>.all()</h3><p>该方法用于将多个Promise实例，包装成一个新的Promise实例。 <code>var p = Promise.all([p1, p2, p3]);</code></p>
<p>Promise.all方法接受一个数组（或具有Iterator接口）作参数，数组中的对象（p1、p2、p3）均为promise实例</p>
<p>（如果不是一个promise，该项会被用Promise.resolve转换为一个promise)。它的状态由这三个promise实例决定。</p>
<pre><code>1. 当p1, p2, p3状态都变为fulfilled，p的状态才会变为fulfilled，并将三个promise返回的结果，按参数

的顺序（而不是 resolved的顺序）存入数组，传给p的回调函数

2. 当p1, p2, p3其中之一状态变为rejected，p的状态也会变为rejected，并把第一个被reject的promise的

返回值，传给p的回调函数，</code></pre><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> p1 = <span class="keyword">new</span> <span class="built_in">Promise</span>(<span class="function"><span class="keyword">function</span> (<span class="params">resolve, reject</span>) </span>&#123;</span><br><span class="line">    setTimeout(resolve, <span class="number">3000</span>, <span class="string">"first"</span>);</span><br><span class="line">&#125;);</span><br><span class="line"><span class="keyword">var</span> p2 = <span class="keyword">new</span> <span class="built_in">Promise</span>(<span class="function"><span class="keyword">function</span> (<span class="params">resolve, reject</span>) </span>&#123;</span><br><span class="line">    resolve(<span class="string">'second'</span>);</span><br><span class="line">&#125;);</span><br><span class="line"><span class="keyword">var</span> p3 = <span class="keyword">new</span> <span class="built_in">Promise</span>(<span class="function">(<span class="params">resolve, reject</span>) =&gt;</span> &#123;</span><br><span class="line">  setTimeout(resolve, <span class="number">1000</span>, <span class="string">"third"</span>);</span><br><span class="line">&#125;); </span><br><span class="line"></span><br><span class="line"><span class="built_in">Promise</span>.all([p1, p2, p3]).then(<span class="function"><span class="keyword">function</span>(<span class="params">values</span>) </span>&#123; </span><br><span class="line">  <span class="built_in">console</span>.log(values); </span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">-------output-------</span><br><span class="line"><span class="comment">//约 3s 后</span></span><br><span class="line">[<span class="string">"first"</span>, <span class="string">"second"</span>, <span class="string">"third"</span>] </span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> p1 = <span class="keyword">new</span> <span class="built_in">Promise</span>(<span class="function">(<span class="params">resolve, reject</span>) =&gt;</span> &#123; </span><br><span class="line">  setTimeout(resolve, <span class="number">1000</span>, <span class="string">"one"</span>); </span><br><span class="line">&#125;); </span><br><span class="line"><span class="keyword">var</span> p2 = <span class="keyword">new</span> <span class="built_in">Promise</span>(<span class="function">(<span class="params">resolve, reject</span>) =&gt;</span> &#123; </span><br><span class="line">  setTimeout(reject, <span class="number">2000</span>, <span class="string">"two"</span>); </span><br><span class="line">&#125;);</span><br><span class="line"><span class="keyword">var</span> p3 = <span class="keyword">new</span> <span class="built_in">Promise</span>(<span class="function">(<span class="params">resolve, reject</span>) =&gt;</span> &#123;</span><br><span class="line">  reject(<span class="string">"three"</span>);</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"><span class="built_in">Promise</span>.all([p1, p2, p3]).then(<span class="function"><span class="keyword">function</span> (<span class="params">value</span>) </span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">'resolve'</span>, value);</span><br><span class="line">&#125;, <span class="function"><span class="keyword">function</span> (<span class="params">error</span>) </span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">'reject'</span>, error);    <span class="comment">// =&gt; reject three</span></span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">-------output-------</span><br><span class="line">reject three</span><br></pre></td></tr></table></figure>

<blockquote>
<p>这多个 promise 是同时开始、并行执行的，而不是顺序执行</p>
</blockquote>
<h3 id="race"><a href="#race" class="headerlink" title=".race()"></a>.race()</h3><p>该方法同样是将多个Promise实例，包装成一个新的Promise实例。<code>var p = Promise.race([p1, p2, p3]);</code></p>
<p><code>Promise.race</code>方法同样接受一个数组（或具有<code>Iterator</code>接口）作参数。当<code>p1, p2, p3</code>中有一个实例的状态发生改变（变为f<code>ulfilled或rejected</code>），<code>p</code>的状态就跟着改变。并把第一个改变状态的<code>promise</code>的返回值，传给p的回调函数。</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> fastPromise = <span class="keyword">new</span> <span class="built_in">Promise</span>(<span class="function"><span class="keyword">function</span> (<span class="params">resolve</span>) </span>&#123;</span><br><span class="line">    setTimeout(<span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">        <span class="built_in">console</span>.log(<span class="string">'fastPromise'</span>);</span><br><span class="line">        resolve(<span class="string">'resolve fastPromise'</span>);</span><br><span class="line">    &#125;, <span class="number">100</span>);</span><br><span class="line">&#125;);</span><br><span class="line"><span class="keyword">var</span> slowPromise = <span class="keyword">new</span> <span class="built_in">Promise</span>(<span class="function"><span class="keyword">function</span> (<span class="params">resolve</span>) </span>&#123;</span><br><span class="line">    setTimeout(<span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">        <span class="built_in">console</span>.log(<span class="string">'slowPromise'</span>);</span><br><span class="line">        resolve(<span class="string">'resolve slowPromise'</span>);</span><br><span class="line">    &#125;, <span class="number">1000</span>);</span><br><span class="line">&#125;);</span><br><span class="line"><span class="comment">// 第一个promise变为resolve后程序停止</span></span><br><span class="line"><span class="built_in">Promise</span>.race([fastPromise, slowPromise]).then(<span class="function"><span class="keyword">function</span> (<span class="params">value</span>) </span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(value);    <span class="comment">// =&gt; resolve fastPromise</span></span><br><span class="line">&#125;);</span><br><span class="line">-------output-------</span><br><span class="line">fastPromise</span><br><span class="line">resolve fastPromise</span><br><span class="line">slowPromise     <span class="comment">//仍会执行</span></span><br></pre></td></tr></table></figure>

<h3 id="resolve"><a href="#resolve" class="headerlink" title=".resolve()"></a>.resolve()</h3><p>它可以看做new Promise()的快捷方式</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">Promise</span>.resolve(<span class="string">'Success'</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">/*******等同于*******/</span></span><br><span class="line"><span class="keyword">new</span> <span class="built_in">Promise</span>(<span class="function"><span class="keyword">function</span> (<span class="params">resolve</span>) </span>&#123;</span><br><span class="line">    resolve(<span class="string">'Success'</span>);</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>

<h2 id="Generator"><a href="#Generator" class="headerlink" title="Generator"></a>Generator</h2><h3 id="它的语法规则"><a href="#它的语法规则" class="headerlink" title="它的语法规则"></a>它的语法规则</h3><p>Generator 函数是一个普通函数，但是有两个特征。一是，function关键字与函数名之间有一个星号；</p>
<p>二是，函数体内部使用yield表达式，定义不同的内部状态（yield在英语里的意思就是“产出”）。</p>
<p>简单实现</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span>* <span class="title">helloWorldGenerator</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">yield</span> <span class="string">'hello'</span>;</span><br><span class="line">  <span class="keyword">yield</span> <span class="string">'world'</span>;</span><br><span class="line">  <span class="keyword">return</span> <span class="string">'ending'</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> hw = helloWorldGenerator();</span><br></pre></td></tr></table></figure>

<p>上面函数它内部有两个yield表达式（hello和world），即该函数有三个状态：hello，world 和 return 语句（结束执行）。</p>
<p>然后，Generator 函数的调用方法与普通函数一样，也是在函数名后面加上一对圆括号。不同的是，调用 </p>
<p>Generator 函数后，该函数并不执行，返回的也不是函数运行结果，而是一个遍历器对象（Iterator Object）。</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">hw.next()</span><br><span class="line"><span class="comment">// &#123; value: 'hello', done: false &#125;</span></span><br><span class="line"></span><br><span class="line">hw.next()</span><br><span class="line"><span class="comment">// &#123; value: 'world', done: false &#125;</span></span><br><span class="line"></span><br><span class="line">hw.next()</span><br><span class="line"><span class="comment">// &#123; value: 'ending', done: true &#125;</span></span><br><span class="line"></span><br><span class="line">hw.next()</span><br><span class="line"><span class="comment">// &#123; value: undefined, done: true &#125;</span></span><br></pre></td></tr></table></figure>

<p>ES6 没有规定，function关键字与函数名之间的星号，写在哪个位置。这导致下面的写法都能通过。</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> * <span class="title">foo</span>(<span class="params">x, y</span>) </span>&#123; ··· &#125;</span><br><span class="line"><span class="function"><span class="keyword">function</span> *<span class="title">foo</span>(<span class="params">x, y</span>) </span>&#123; ··· &#125;</span><br><span class="line"><span class="function"><span class="keyword">function</span>* <span class="title">foo</span>(<span class="params">x, y</span>) </span>&#123; ··· &#125;</span><br><span class="line"><span class="function"><span class="keyword">function</span>*<span class="title">foo</span>(<span class="params">x, y</span>) </span>&#123; ··· &#125;</span><br></pre></td></tr></table></figure>

<p>由于 Generator 函数仍然是普通函数，所以一般的写法是上面的第三种，即星号紧跟在function关键字后面。</p>
<h3 id="yield表达式"><a href="#yield表达式" class="headerlink" title="yield表达式"></a>yield表达式</h3><ul>
<li><p>yield是ES6的新关键字，使生成器函数执行暂停，yield关键字后面的表达式的值返回给生成器的调用者。它可以被认为是一个基于生成器的版本的return关键字。</p>
</li>
<li><p>yield关键字实际返回一个IteratorResult（迭代器）对象，它有两个属性，value和done，分别代表返回值和是否完成。</p>
</li>
<li><p>yield无法单独工作，需要配合generator(生成器)的其他函数，如next，懒汉式操作，展现强大的主动控制特性。</p>
</li>
</ul>
<p>而且它只能用在遍历器函数里面,并且它有一个返回值{value: xxx,done: false},value就是当前遍历器暂停时返回</p>
<p>的结果，done为false得时候，表示遍历器没遍历完，为true表示遍历已结束。</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> *<span class="title">foo</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">  <span class="keyword">var</span> x = <span class="number">1</span>;</span><br><span class="line">  y = <span class="keyword">yield</span>(x+<span class="number">1</span>);</span><br><span class="line">  <span class="keyword">return</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">var</span> f = foo();</span><br></pre></td></tr></table></figure>

<p>遍历器函数一个重要的特点就是需要next()方法才能执行，所以上面f = foo()什么都没发生，要用<code>f.next();</code></p>
<p><code>f.next()</code>是遍历器第一次执行，当遍历至关键字<code>yield</code>时，函数暂停，并返回yield后面的值，所以此时返回<code>{value: 2,done: false}</code></p>
<p>再执行一次<code>f.next()</code>,那么遍历器函数则从上次暂停的<code>yield</code>处开始，直接到<code>return</code>语句，所以结果是<code>{value: undefined,done: true}</code></p>
<p>next()可以接收参数，就是可以将传入的参数作用于上一次yield</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> f = <span class="function"><span class="keyword">function</span> *(<span class="params"></span>)</span>&#123;</span><br><span class="line">  <span class="keyword">var</span> x = <span class="number">1</span>;</span><br><span class="line">  <span class="keyword">var</span> y = <span class="keyword">yield</span>(x+<span class="number">1</span>);</span><br><span class="line">  <span class="keyword">var</span> z = <span class="keyword">yield</span>(x+y);</span><br><span class="line">  <span class="keyword">return</span> z;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">var</span> a = f.next();   <span class="comment">// 2</span></span><br><span class="line"><span class="keyword">var</span> b = f.next(<span class="number">2</span>);  <span class="comment">// 3</span></span><br><span class="line"><span class="keyword">var</span> c = f.next(<span class="number">4</span>);  <span class="comment">// 4</span></span><br></pre></td></tr></table></figure>

<p>第一次执行暂停于<code>yield(x+1)</code>,并返回于<code>x+1</code>等于2</p>
<p>第二次执行，<code>next()</code>的参数<code>2</code>,就代替了上面的<code>yield(x+1)</code>，所以<code>y=2</code>,那么暂停于第二个<code>yield yield(x+y)</code>并返回<code>x+y</code>等于<code>3</code><br>同理,第三次执行<code>z=4，return z</code>等于<code>4</code></p>
<blockquote>
<p>注意: next()可以接受一个函数，将函数执行的结果返回 作为其值</p>
</blockquote>
<h2 id="Reflect"><a href="#Reflect" class="headerlink" title="Reflect"></a>Reflect</h2><h3 id="为什么要设计Reflect？"><a href="#为什么要设计Reflect？" class="headerlink" title="为什么要设计Reflect？"></a>为什么要设计Reflect？</h3><p>（1）将Object对象的属于语言内部的方法放到Reflect对象上，即从Reflect对象上拿Object对象内部方法。<br>（2）将用 老Object方法 报错的情况，改为返回false</p>
<p>老写法</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">try</span> &#123;</span><br><span class="line">  <span class="built_in">Object</span>.defineProperty(target, property, attributes);</span><br><span class="line">  <span class="comment">// success</span></span><br><span class="line">&#125; <span class="keyword">catch</span> (e) &#123;</span><br><span class="line">  <span class="comment">// failure</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>新写法</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span> (<span class="built_in">Reflect</span>.defineProperty(target, property, attributes)) &#123;</span><br><span class="line">  <span class="comment">// success</span></span><br><span class="line">&#125; <span class="keyword">else</span> &#123;</span><br><span class="line">  <span class="comment">// failure</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>（3）让Object操作变成函数行为</p>
<p>老写法（命令式写法）</p>
<p><code>&#39;name&#39; in Object //true</code></p>
<p>新写法</p>
<p><code>Reflect.has(Object,&#39;name&#39;) //true</code></p>
<p>（4）Reflect与Proxy是相辅相成的，在Proxy上有的方法，在Reflect就一定有</p>
<h3 id="Reflect的常用API"><a href="#Reflect的常用API" class="headerlink" title="Reflect的常用API"></a>Reflect的常用API</h3><ol>
<li>Reflect.get(target,property,receiver)</li>
</ol>
<p>与从 对象 (target[propertyKey]) 中读取属性类似，但它是通过一个函数执行来操作的。</p>
<p><code>target</code>为需要取值的目标对象，<code>propertyKey</code>需要获取的值的键值，<code>receiver</code>为如果<code>target</code>对象中指定了<code>getter</code>，<code>receiver</code>则为<code>getter</code>调用时的<code>this</code>值。</p>
<blockquote>
<p>注意：如果Reflect.get()的第一个参数不是对象，则会报错。</p>
</blockquote>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// Object</span></span><br><span class="line"><span class="keyword">var</span> obj = &#123; <span class="attr">x</span>: <span class="number">1</span>, <span class="attr">y</span>: <span class="number">2</span> &#125;;</span><br><span class="line"><span class="built_in">Reflect</span>.get(obj, <span class="string">"x"</span>); <span class="comment">// 1</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// Array</span></span><br><span class="line"><span class="built_in">Reflect</span>.get([<span class="string">"zero"</span>, <span class="string">"one"</span>], <span class="number">1</span>); <span class="comment">// "one"</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// Proxy with a get handler</span></span><br><span class="line"><span class="keyword">var</span> x = &#123;<span class="attr">p</span>: <span class="number">1</span>&#125;;</span><br><span class="line"><span class="keyword">var</span> obj = <span class="keyword">new</span> <span class="built_in">Proxy</span>(x, &#123;</span><br><span class="line">  <span class="keyword">get</span>(t, k, r) &#123; <span class="keyword">return</span> k + <span class="string">"bar"</span>; &#125;</span><br><span class="line">&#125;);</span><br><span class="line"><span class="built_in">Reflect</span>.get(obj, <span class="string">"foo"</span>); <span class="comment">// "foobar"</span></span><br></pre></td></tr></table></figure>

<ol start="2">
<li>Reflect.set(target,propName,propValue,receiver)</li>
</ol>
<p>就像在一个对象上设置一个属性。</p>
<p><code>target</code>:需要取值的目标对象,<code>propertyKey</code>:需要获取的值的键值,<code>receiver</code>:如果<code>target</code>对象中指定了<code>getter</code>，<code>receiver</code>则为<code>getter</code>调用时的<code>this</code>值。</p>
<blockquote>
<p>如果目标值类型不是 Object，则抛出一个 TypeError。</p>
</blockquote>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// Object</span></span><br><span class="line"><span class="keyword">var</span> obj = &#123;&#125;;</span><br><span class="line"><span class="built_in">Reflect</span>.set(obj, <span class="string">"prop"</span>, <span class="string">"value"</span>); <span class="comment">// true</span></span><br><span class="line">obj.prop; <span class="comment">// "value"</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// Array</span></span><br><span class="line"><span class="keyword">var</span> arr = [<span class="string">"duck"</span>, <span class="string">"duck"</span>, <span class="string">"duck"</span>];</span><br><span class="line"><span class="built_in">Reflect</span>.set(arr, <span class="number">2</span>, <span class="string">"goose"</span>); <span class="comment">// true</span></span><br><span class="line">arr[<span class="number">2</span>]; <span class="comment">// "goose"</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// It can truncate an array.</span></span><br><span class="line"><span class="built_in">Reflect</span>.set(arr, <span class="string">"length"</span>, <span class="number">1</span>); <span class="comment">// true</span></span><br><span class="line">arr; <span class="comment">// ["duck"];</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// With just one argument, propertyKey and value are "undefined".</span></span><br><span class="line"><span class="keyword">var</span> obj = &#123;&#125;;</span><br><span class="line"><span class="built_in">Reflect</span>.set(obj); <span class="comment">// true</span></span><br><span class="line"><span class="built_in">Reflect</span>.getOwnPropertyDescriptor(obj, <span class="string">"undefined"</span>);</span><br><span class="line"><span class="comment">// &#123; value: undefined, writable: true, enumerable: true, configurable: true &#125;</span></span><br></pre></td></tr></table></figure>

<ol start="3">
<li>Reflect.has()</li>
</ol>
<p>作用与 in 操作符 相同。</p>
<p><code>target</code>目标对象. <code>propertyKey</code>:属性名，需要检查目标对象是否存在此属性。</p>
<blockquote>
<p>如果目标对象并非Object 类型，抛出TypeError。</p>
</blockquote>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> obj= &#123;</span><br><span class="line">  name: <span class="string">"chen"</span>,</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>

<p>老写法 <code>&#39;name&#39; in obj // true</code></p>
<p>新写法<code>Reflect.has(obj, &#39;name&#39;) // true</code></p>
<p>参考文章：</p>
<p><a href="https://www.jianshu.com/p/4a5eca0536c3" target="_blank" rel="noopener">ES6之Reflect</a></p>
<p><a href="https://segmentfault.com/a/1190000010471230" target="_blank" rel="noopener">《深入理解ES6》笔记——代理（Proxy）和反射（Reflection）API（12）</a></p>
<p><a href="https://blog.csdn.net/u013707249/article/details/78842602" target="_blank" rel="noopener">ES6黑科技实践–proxy,reflect</a></p>
<h2 id="Map"><a href="#Map" class="headerlink" title="Map"></a>Map</h2><p>javascript的Object本身就是键值对的数据结构，但实际上属性和值构成的是”字符串-值“对，属性只能是字符串，如果传个对象字面量作为属性名，那么会默认把对象转换成字符串，结果这个属性名就变成”[object Object]“。</p>
<p>ES6提供了”值-值“对的数据结构，键名不仅可以是字符串，也可以是对象。它是一个更完善的Hash结构。</p>
<ol>
<li>键值对，键可以是对象。<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> map1 = <span class="keyword">new</span> <span class="built_in">Map</span>()</span><br><span class="line"><span class="keyword">const</span> objkey = &#123;<span class="attr">p1</span>: <span class="string">'v1'</span>&#125;</span><br><span class="line"></span><br><span class="line">map1.set(objkey, <span class="string">'hello'</span>)</span><br><span class="line"><span class="built_in">console</span>.log(map1.get(objkey))</span><br></pre></td></tr></table></figure>

</li>
</ol>
<p>结果：<code>hello</code></p>
<ol start="2">
<li><p>Map可以接受数组作为参数，数组成员还是一个数组，其中有两个元素，一个表示键一个表示值。</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> map2 = <span class="keyword">new</span> <span class="built_in">Map</span>([</span><br><span class="line">  [<span class="string">'name'</span>, <span class="string">'Aissen'</span>],</span><br><span class="line">  [<span class="string">'age'</span>, <span class="number">12</span>]</span><br><span class="line">])</span><br><span class="line"><span class="built_in">console</span>.log(map2.get(<span class="string">'name'</span>))</span><br><span class="line"><span class="built_in">console</span>.log(map2.get(<span class="string">'age'</span>))</span><br><span class="line"><span class="string">``</span><span class="string">`      </span></span><br><span class="line"><span class="string">结果：</span></span><br><span class="line"><span class="string">`</span><span class="string">``</span>js</span><br><span class="line">Aissen</span><br><span class="line"><span class="number">12</span></span><br></pre></td></tr></table></figure>
</li>
<li><p>size  获取map的大小。</p>
</li>
<li><p>get 获取键对应的值。</p>
</li>
<li><p>has 判断指定的键是否存在。</p>
</li>
<li><p>delete  删除键值对。</p>
</li>
<li><p>clear 删除map中的所有键值对</p>
</li>
<li><p>set 设置键值对，键可以是各种类型，包括undefined，function。</p>
</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> map4 = <span class="keyword">new</span> <span class="built_in">Map</span>();</span><br><span class="line">map4.set(<span class="string">'k1'</span>, <span class="number">6</span>)        <span class="comment">// 键是字符串</span></span><br><span class="line">map4.set(<span class="number">222</span>, <span class="string">'哈哈哈'</span>)     <span class="comment">// 键是数值</span></span><br><span class="line">map4.set(<span class="literal">undefined</span>, <span class="string">'gagaga'</span>)    <span class="comment">// 键是 undefined</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> fun = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;<span class="built_in">console</span>.log(<span class="string">'hello'</span>);&#125;</span><br><span class="line">map4.set(fun, <span class="string">'fun'</span>) <span class="comment">// 键是 function</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log(<span class="string">'map4 size: %s'</span>, map4.size)</span><br><span class="line"><span class="built_in">console</span>.log(<span class="string">'undefined value: %s'</span>, map4.get(<span class="literal">undefined</span>))</span><br><span class="line"><span class="built_in">console</span>.log(<span class="string">'fun value: %s'</span>, map4.get(fun))</span><br></pre></td></tr></table></figure>

<p>结果：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">map4 size: <span class="number">4</span></span><br><span class="line"><span class="literal">undefined</span> value: gagaga</span><br><span class="line">fun value: fun</span><br></pre></td></tr></table></figure>

<p>也可对set进行链式调用。</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">map4.set(<span class="string">'k2'</span>, <span class="number">2</span>).set(<span class="string">'k3'</span>, <span class="number">4</span>).set(<span class="string">'k4'</span>, <span class="number">5</span>)</span><br><span class="line"><span class="built_in">console</span>.log(<span class="string">'map4 size: %s'</span>, map4.size)</span><br></pre></td></tr></table></figure>

<p>结果：<code>map4 size: 7</code></p>
<p>参考文章<br><a href="https://www.cnblogs.com/kongxianghai/p/7309735.html" target="_blank" rel="noopener">ES6，新增数据结构Map的用法</a></p>

          
        
      
    </div>

    
    
    
      <footer class="post-footer">
          <div class="post-eof"></div>
        
      </footer>
  </div>
  
  
  
  </article>

    
      

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="http://yoursite.com/2019/11/14/2019/11/Hexo搭建个人博客/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="淡退">
      <meta itemprop="description" content="欢迎你的到来！">
      <meta itemprop="image" content="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1565847089857&di=2bb546a711f57b819a4dbf3584c66392&imgtype=0&src=http%3A%2F%2Fhbimg.b0.upaiyun.com%2F458af12108c4da0f1cf4fe8e2713a458898e332b28196-jdjJ3j_fw658">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="淡退">
    </span>
      <header class="post-header">
        
          <i class="fa fa-thumb-tack"></i>
          <font color=7D26CD>置顶</font>
        

        
          <h1 class="post-title" itemprop="name headline">
              
              <a href="/2019/11/14/2019/11/Hexo搭建个人博客/" class="post-title-link" itemprop="url">Hexo搭建个人博客</a>
            
          </h1>
        

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              <span class="post-meta-item-text">发表于</span>

              
                
              

              <time title="创建时间：2019-11-14 23:10:17" itemprop="dateCreated datePublished" datetime="2019-11-14T23:10:17+08:00">2019-11-14</time>
            </span>
          
            

            
              <span class="post-meta-item">
                <span class="post-meta-item-icon">
                  <i class="fa fa-calendar-check-o"></i>
                </span>
                <span class="post-meta-item-text">更新于</span>
                <time title="修改时间：2020-01-03 16:30:31" itemprop="dateModified" datetime="2020-01-03T16:30:31+08:00">2020-01-03</time>
              </span>
            
          
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="fa fa-folder-o"></i>
              </span>
              <span class="post-meta-item-text">分类于</span>
              
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing"><a href="/categories/hexo/" itemprop="url" rel="index"><span itemprop="name">hexo</span></a></span>

                
                
              
            </span>
          

          

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
        <div class="post-gallery" itemscope itemtype="http://schema.org/ImageGallery">
            <div class="post-gallery-row">
              <img src="https://desk-fd.zol-img.com.cn/t_s1440x900c5/g5/M00/0C/00/ChMkJ13VHGeIQbMvAAZiH-yBkAsAAvVdQCGfhkABmI3388.jpg" itemprop="contentUrl">
            
          

          </div>
        </div>
          
            <a id="more"></a>
<h2 id="准备环境"><a href="#准备环境" class="headerlink" title="准备环境"></a>准备环境</h2><ol>
<li>安装 Node</li>
<li>安装 Git</li>
<li>注册码云或者github</li>
<li>安装 Hexo</li>
</ol>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install hexo-cli -g</span><br></pre></td></tr></table></figure>

<ul>
<li>出现下图表示安装成功</li>
</ul>
<p><img src="http://zwd.yyzheng.cn/hexo_manong_blog/933c7992797c0f0fs.png" alt></p>
<h2 id="搭建本地个人博客"><a href="#搭建本地个人博客" class="headerlink" title="搭建本地个人博客"></a>搭建本地个人博客</h2><h3 id="初始化-hexo"><a href="#初始化-hexo" class="headerlink" title="初始化 hexo"></a>初始化 hexo</h3><ul>
<li>新建一个空白文件夹（下文提到的“项目根目录”是指你新建的文件夹的位置）用于存放 hexo 资源。在空白文件夹里面打开 Git Bash ，输入下列命令行进行初始化，初始化成功后会在文件夹生成如下图的文件。</li>
</ul>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">hexo init</span><br></pre></td></tr></table></figure>

<p><img src="http://zwd.yyzheng.cn/hexo_manong_blog/2454d988bda5f01es.png" alt></p>
<h3 id="生成静态页面"><a href="#生成静态页面" class="headerlink" title="生成静态页面"></a>生成静态页面</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">hexo g</span><br></pre></td></tr></table></figure>

<h3 id="启动本地服务"><a href="#启动本地服务" class="headerlink" title="启动本地服务"></a>启动本地服务</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">hexo s</span><br></pre></td></tr></table></figure>

<ul>
<li>关闭本地服务器在 Git Bash 界面按 Ctrl+C， 在浏览器输入：<a href="http://localhost:4000" target="_blank" rel="noopener">http://localhost:4000</a> 查看</li>
</ul>
<p><img src="http://zwd.yyzheng.cn/hexo_manong_blog/ecc250d77459285bs.png" alt></p>
<h2 id="美化个人博客"><a href="#美化个人博客" class="headerlink" title="美化个人博客"></a>美化个人博客</h2><h3 id="博客主题设置"><a href="#博客主题设置" class="headerlink" title="博客主题设置"></a>博客主题设置</h3><h4 id="克隆主题"><a href="#克隆主题" class="headerlink" title="克隆主题"></a>克隆主题</h4><ul>
<li>在项目根目录下的 themes 文件中，打开 Git Bash ，用命令行克隆下新的主题。我这里用的 Next 主题，需要其他主题的自己百度找。</li>
</ul>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git clone https://github.com/theme-next/hexo-theme-next.git</span><br></pre></td></tr></table></figure>

<p><img src="http://zwd.yyzheng.cn/hexo_manong_blog/3e09b4d14b279371s.png" alt></p>
<h3 id="配置主题"><a href="#配置主题" class="headerlink" title="配置主题"></a>配置主题</h3><ul>
<li>用文本的方式打开项目根目录下的 _config.yml 配置文件，找到 theme 把原来默认的 landscape 主题名字，改成刚刚克隆的主题名字（主题名字为上图中文件夹的名字）。</li>
</ul>
<p><img src="http://zwd.yyzheng.cn/hexo_manong_blog/7a032ed5279bfee2s.png" alt></p>
<h3 id="测试主题"><a href="#测试主题" class="headerlink" title="测试主题"></a>测试主题</h3><ul>
<li>重新回到项目根目录下，打开 Git Bath ，用命令行启动服务器。在浏览器访问 <a href="http://localhost:4000" target="_blank" rel="noopener">http://localhost:4000</a></li>
</ul>
<p><img src="http://zwd.yyzheng.cn/hexo_manong_blog/51e4059c599bbd2fs.png" alt></p>
<h3 id="发布文章"><a href="#发布文章" class="headerlink" title="发布文章"></a>发布文章</h3><ul>
<li>方法一：在项目根目录下，打开 Git Bash ，执行新建命令，然后 hexo 会自动在指定目录下生成对应文件，如下图所示。然后找到新建好的文件，打开即可进行编辑。</li>
</ul>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">hexo new &quot;此处输入文章名字&quot;</span><br></pre></td></tr></table></figure>

<p><img src="http://zwd.yyzheng.cn/hexo_manong_blog/596fc4a69978bed5s.png" alt></p>
<ul>
<li>方法二：可以直接把已经准备的 md 格式的文章复制到 项目名称 /source/_posts 目录下，然后打开文件，在文件头加入 front-matter 部分，title 表示文章标题，date 表示发布时间。如图所示，图片上用到的其他参数，后面会介绍到。</li>
</ul>
<blockquote>
<p>front-matte 书写的时候要注意，冒号后面要跟一个空格号</p>
</blockquote>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">---</span><br><span class="line">title: a</span><br><span class="line">date: 2019-04-14 23:10:17</span><br><span class="line">---</span><br></pre></td></tr></table></figure>

<p><img src="http://zwd.yyzheng.cn/hexo_manong_blog/e9512a34d0ffddaas.png" alt></p>
<ul>
<li>准备好 md 格式文件后，使用下面命令生成网站静态文件到默认设置的 public 文件夹，然后再启动本地服务器。<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">hexo g</span><br></pre></td></tr></table></figure>

</li>
</ul>
<h3 id="主题风格设置"><a href="#主题风格设置" class="headerlink" title="主题风格设置"></a>主题风格设置</h3><ul>
<li><p>打开主题文件夹下的 _config.yml 配置文件（注意：这里要区别，不是項目根目录，主题文件夹的路径为：新建空白文件夹名称/themes/主题文件夹名称）。通过查找功能找到 Schemes 模块，修改为 Gemini 风格。如果喜欢其他风格可以自己修改。如下图所示：<br><img src="http://zwd.yyzheng.cn/hexo_manong_blog/57735b310de44a59s.png" alt></p>
</li>
<li><p>刷新页面可以看到新风格的界面如下图所示：<br><img src="http://zwd.yyzheng.cn/hexo_manong_blog/a17bbca793681dbes.png" alt></p>
</li>
</ul>
<h3 id="博客左侧栏设置"><a href="#博客左侧栏设置" class="headerlink" title="博客左侧栏设置"></a>博客左侧栏设置</h3><ul>
<li>在上面的网站界面，可以发现网站的文字是英文，只要修改一下语言模式即可。打开根目录文件夹下的 _config.yml 配置文件。找到 language，设置为 zh-CN。标题等其他参数的设置如下。可以对照效果图的具体位置，根据自己的实际需求进行修改。（注意：修改了项目根目录下的 _config.yml配置文件，需要重启部署项目后才能生效）</li>
</ul>
<p><img src="http://zwd.yyzheng.cn/hexo_manong_blog/cf7f8b7318ba13aes.png" alt><br><img src="http://zwd.yyzheng.cn/hexo_manong_blog/89e91ba175bfc5d7s.png" alt><br><img src="http://zwd.yyzheng.cn/hexo_manong_blog/89e91ba175bfc5d7s.png" alt></p>
<h3 id="分类设置"><a href="#分类设置" class="headerlink" title="分类设置"></a>分类设置</h3><h4 id="添加分类列表"><a href="#添加分类列表" class="headerlink" title="添加分类列表"></a>添加分类列表</h4><ul>
<li>在项目根目录下，执行下面的命令行，新建分类页面，然后会在项目根目录下的 source 文件夹中新建一个 categories 文件夹。<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">hexo new page categories</span><br></pre></td></tr></table></figure>

</li>
</ul>
<p><img src="http://zwd.yyzheng.cn/hexo_manong_blog/ec8bf34d15fb441es.png" alt></p>
<ul>
<li>打开 categories 文件夹中的 index.md 文件，添加 type 字段，设置为 “categories”。如下图所示。</li>
</ul>
<p><img src="http://zwd.yyzheng.cn/hexo_manong_blog/8b72d1e4839a457fs.png" alt></p>
<ul>
<li>接着到主题文件夹下的 _config.yml 配置文件下，找到 menu 模块，把 categories 的注释给去掉。如下图所示。</li>
</ul>
<p><img src="http://zwd.yyzheng.cn/hexo_manong_blog/3205c65c02e1d02cs.png" alt></p>
<ul>
<li>刷新页面（如果刷新没效果，可以重启服务），可以在页面左侧栏上看到多了一个“分类”列表。</li>
<li><img src="http://zwd.yyzheng.cn/hexo_manong_blog/3c0bcb4e00b69674s.png" alt></li>
</ul>
<h4 id="如何将文章添加到对应分类？"><a href="#如何将文章添加到对应分类？" class="headerlink" title="如何将文章添加到对应分类？"></a>如何将文章添加到对应分类？</h4><ul>
<li>文章发布前，在 front-matter 部分，多写一个 categories 字段，然后参数写上类别的名称，保存后重启服务，在网页上点击“分类”，可以看到分类下已经生成了刚刚设置的类别，并把刚刚发布的文章归类在此类别下。如下图所示。<br><img src="http://zwd.yyzheng.cn/hexo_manong_blog/9c256cae759cdcffs.png" alt></li>
</ul>
<h3 id="标签设置"><a href="#标签设置" class="headerlink" title="标签设置"></a>标签设置</h3><ul>
<li>方法跟分类设置一样，所以不再赘述介绍</li>
<li>但是需要补充一点， front-matter 中字段有多个参数的时候，可以使用如下图的写法。<br><img src="http://zwd.yyzheng.cn/hexo_manong_blog/7f1dc337505102c6s.png" alt></li>
</ul>
<h3 id="Hexo-博客添加站内搜索"><a href="#Hexo-博客添加站内搜索" class="headerlink" title="Hexo 博客添加站内搜索"></a>Hexo 博客添加站内搜索</h3><ul>
<li><p>NexT主题支持集成 Swiftype、 微搜索、Local Search 和 Algolia。下面介绍 Local Search 的安装吧。注意：安装的时候要是项目根目录下安装。</p>
</li>
<li><p>安装 hexo-generator-search</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install hexo-generator-search --save</span><br></pre></td></tr></table></figure>
</li>
<li><p>安装 hexo-generator-searchdb</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install hexo-generator-searchdb --save</span><br></pre></td></tr></table></figure>
</li>
<li><p>在项目根目录下的 _config.yml 配置文件的文末添加下面这段代码。</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">search:</span><br><span class="line">  path: search.xml</span><br><span class="line">  field: post</span><br><span class="line">  format: html</span><br><span class="line">  limit: 10000</span><br></pre></td></tr></table></figure>
</li>
<li><p>编辑主题文件夹的 _config.yml 配置文件，设置 Local searchenable 为 ture。<br><img src="http://zwd.yyzheng.cn/hexo_manong_blog/7c51e609df9e5c42s.png" alt></p>
</li>
<li><p>重启服务，效果图如下：<br><img src="http://zwd.yyzheng.cn/hexo_manong_blog/f92ee473a8c701cds.png" alt></p>
</li>
</ul>
<h3 id="博客头像设置"><a href="#博客头像设置" class="headerlink" title="博客头像设置"></a>博客头像设置</h3><h4 id="添加博客头像"><a href="#添加博客头像" class="headerlink" title="添加博客头像"></a>添加博客头像</h4><ul>
<li>打开主题文件夹下的 _config.yml 配置文件，通过查找功能找到 avatar，然后把一个在线的头像图片地址（百度图片中直接复制链接即可），作为 url 的参数。如下图所示：<br><img src="http://zwd.yyzheng.cn/hexo_manong_blog/a0137663728e3f0fs.png" alt></li>
<li>然后刷新页面，可以看到网站上已经显示了相应的头像了：<br><img src="http://zwd.yyzheng.cn/hexo_manong_blog/c8ee1492e43b626as.png" alt></li>
</ul>
<h4 id="设置头像圆角并旋转打开"><a href="#设置头像圆角并旋转打开" class="headerlink" title="设置头像圆角并旋转打开"></a>设置头像圆角并旋转打开</h4><ul>
<li><p>打开主题文件夹的 source\css_common\components\sidebar 目录下的 sidebar-author.styl 文件，然后把下面的代码添加进去即可。</p>
<figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-class">.site-author-image</span> &#123;</span><br><span class="line">  <span class="attribute">display</span>: block;</span><br><span class="line">  <span class="attribute">margin</span>: <span class="number">0</span> auto;</span><br><span class="line">  <span class="attribute">padding</span>: $site-author-image-padding;</span><br><span class="line">  <span class="attribute">max-width</span>: $site-author-image-width;</span><br><span class="line">  <span class="attribute">height</span>: $site-author-image-height;</span><br><span class="line">  <span class="attribute">border</span>: $site-author-image-border-width solid $site-author-image-border-color;</span><br><span class="line">  <span class="comment">/* 头像圆形 */</span></span><br><span class="line">  <span class="attribute">border-radius</span>: <span class="number">80px</span>;</span><br><span class="line">  <span class="attribute">-webkit-border-radius</span>: <span class="number">80px</span>;</span><br><span class="line">  <span class="attribute">-moz-border-radius</span>: <span class="number">80px</span>;</span><br><span class="line">  <span class="attribute">box-shadow</span>: inset <span class="number">0</span> -<span class="number">1px</span> <span class="number">0</span> <span class="number">#333</span>sf;</span><br><span class="line">  <span class="comment">/* 设置循环动画 [animation: (play)动画名称 (2s)动画播放时长单位秒或微秒 (ase-out)动画播放的速度曲线为以低速结束 </span></span><br><span class="line"><span class="comment">    (1s)等待1秒然后开始动画 (1)动画播放次数(infinite为循环播放) ]*/</span></span><br><span class="line"> </span><br><span class="line">  <span class="comment">/* 鼠标经过头像旋转360度 */</span></span><br><span class="line">  <span class="attribute">-webkit-transition</span>: -webkit-transform <span class="number">1.0s</span> ease-out;</span><br><span class="line">  <span class="attribute">-moz-transition</span>: -moz-transform <span class="number">1.0s</span> ease-out;</span><br><span class="line">  <span class="attribute">transition</span>: transform <span class="number">1.0s</span> ease-out;</span><br><span class="line">&#125;</span><br><span class="line"><span class="selector-tag">img</span><span class="selector-pseudo">:hover</span> &#123;</span><br><span class="line">  <span class="comment">/* 鼠标经过停止头像旋转 </span></span><br><span class="line"><span class="comment">  -webkit-animation-play-state:paused;</span></span><br><span class="line"><span class="comment">  animation-play-state:paused;*/</span></span><br><span class="line">  <span class="comment">/* 鼠标经过头像旋转360度 */</span></span><br><span class="line">  <span class="attribute">-webkit-transform</span>: <span class="built_in">rotateZ</span>(360deg);</span><br><span class="line">  <span class="attribute">-moz-transform</span>: <span class="built_in">rotateZ</span>(360deg);</span><br><span class="line">  <span class="attribute">transform</span>: <span class="built_in">rotateZ</span>(360deg);</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">/* Z 轴旋转动画 */</span></span><br><span class="line">@-<span class="keyword">webkit</span>-<span class="keyword">keyframes</span> play &#123;</span><br><span class="line">  0% &#123;</span><br><span class="line">    <span class="attribute">-webkit-transform</span>: <span class="built_in">rotateZ</span>(0deg);</span><br><span class="line">  &#125;</span><br><span class="line">  100% &#123;</span><br><span class="line">    <span class="attribute">-webkit-transform</span>: <span class="built_in">rotateZ</span>(-360deg);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line">@-<span class="keyword">moz</span>-<span class="keyword">keyframes</span> play &#123;</span><br><span class="line">  0% &#123;</span><br><span class="line">    <span class="attribute">-moz-transform</span>: <span class="built_in">rotateZ</span>(0deg);</span><br><span class="line">  &#125;</span><br><span class="line">  100% &#123;</span><br><span class="line">    <span class="attribute">-moz-transform</span>: <span class="built_in">rotateZ</span>(-360deg);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line">@<span class="keyword">keyframes</span> play &#123;</span><br><span class="line">  0% &#123;</span><br><span class="line">    <span class="attribute">transform</span>: <span class="built_in">rotateZ</span>(0deg);</span><br><span class="line">  &#125;</span><br><span class="line">  100% &#123;</span><br><span class="line">    <span class="attribute">transform</span>: <span class="built_in">rotateZ</span>(-360deg);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>效果图如下：<br><img src="http://zwd.yyzheng.cn/hexo_manong_blog/0a14468ce0d901d9.gif" alt></p>
</li>
</ul>
<h3 id="网页背景设置"><a href="#网页背景设置" class="headerlink" title="网页背景设置"></a>网页背景设置</h3><ul>
<li>打开主题文件夹下的 source 文件夹，进入 css/_custom 文件下，用文本形式打开 custom.styl 文件，然后添加下面这段代码。代码中 url 的地址是指到： 主题文件夹/source/images/ 。<figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-tag">body</span>&#123;</span><br><span class="line">    <span class="attribute">background</span>:<span class="built_in">url</span>(/images/bg.jpg);</span><br><span class="line">    <span class="attribute">background-size</span>:cover;</span><br><span class="line">    <span class="attribute">background-repeat</span>:no-repeat;</span><br><span class="line">    <span class="attribute">background-attachment</span>:fixed;</span><br><span class="line">    <span class="attribute">background-position</span>:center;</span><br><span class="line">    // 设置主题部分的透明度，具体看图</span><br><span class="line">    <span class="selector-tag">opacity</span>: 0<span class="selector-class">.8</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

</li>
</ul>
<p>效果图如下：<br><img src="http://zwd.yyzheng.cn/hexo_manong_blog/3d0102f69054f0e6s.png" alt></p>
<h3 id="首页文章预览设置"><a href="#首页文章预览设置" class="headerlink" title="首页文章预览设置"></a>首页文章预览设置</h3><ul>
<li><p>默认情况下，文章在首页是全文显示的，这样肯定是不方便读者浏览。所以需要实现预览模式。效果图如下：<br><img src="http://zwd.yyzheng.cn/hexo_manong_blog/5e832db322ee611es.png" alt></p>
</li>
<li><p>方法一：使用 &lt; !–more–&gt; 手动切断</p>
</li>
</ul>
<p>这种方法可以根据文章的内容，自己在合适的位置添加 &lt; !–more–&gt; 标签，使用灵活，也是Hexo推荐的方法。</p>
<ul>
<li>方法二：添加 description</li>
</ul>
<p>在文章的 front-matter 中添加 description 和 photos 字段，如下图所示。如果不需要显示图片的话，可以把 photos 去掉。<br>ps：不知道 front-matter 是什么的话，跳转到第二章的第4点的发布文章看下。<br><img src="http://zwd.yyzheng.cn/hexo_manong_blog/df10c8fb9de7b7b8s.png" alt></p>
<ul>
<li>方法三：自动形成摘要</li>
</ul>
<p>在主题文件下的_config.yml配置文件中添加默认截取的长度为 150 字符，可以根据需要自行设定。</p>
<h3 id="设置网站图片-Favicon"><a href="#设置网站图片-Favicon" class="headerlink" title="设置网站图片 Favicon"></a>设置网站图片 Favicon</h3><ul>
<li>在 阿里巴巴矢量图标库 中找到自己的喜欢的图标，下载下来，覆盖掉主题文件夹下的 source/images 目录里面的三张图片即可。<br><img src="http://zwd.yyzheng.cn/hexo_manong_blog/c4e5e945c3a1c0d5s.png" alt></li>
</ul>
<h3 id="网页顶部进度加载条设置"><a href="#网页顶部进度加载条设置" class="headerlink" title="网页顶部进度加载条设置"></a>网页顶部进度加载条设置</h3><p><img src="http://zwd.yyzheng.cn/hexo_manong_blog/00fc9d55b074d32es.png" alt></p>
<h3 id="博客置顶设置"><a href="#博客置顶设置" class="headerlink" title="博客置顶设置"></a>博客置顶设置</h3><ul>
<li><p>安装插件</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">npm uninstall hexo-generator-index --save</span><br><span class="line">npm install hexo-generator-index-pin-top --save</span><br></pre></td></tr></table></figure>
</li>
<li><p>然后在需要置顶的文章的 Front-matter 中加上 top 即可，数值越大表示等级越高，越靠前显示。</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">---</span><br><span class="line">title: this is my first blog</span><br><span class="line">date: 2019-04-14</span><br><span class="line">top: 100</span><br><span class="line">---</span><br></pre></td></tr></table></figure>

</li>
</ul>
<p>-在主题文件夹中打开 layout/_macro/post.swig 文件，定位到 post-header ，把下面的代码添加进去即可。</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">&#123;% if post.top %&#125;</span><br><span class="line">  &lt;i class=&quot;fa fa-thumb-tack&quot;&gt;&lt;/i&gt;</span><br><span class="line">  &lt;font color=7D26CD&gt;置顶&lt;/font&gt;</span><br><span class="line">&#123;% endif %&#125;</span><br></pre></td></tr></table></figure>

<p><img src="http://zwd.yyzheng.cn/hexo_manong_blog/8b095f7c592707bas.png" alt></p>
<ul>
<li>重启服务，效果图如下：<br><img src="http://zwd.yyzheng.cn/hexo_manong_blog/51bfdaba5f3841a0s.png" alt></li>
</ul>
<h3 id="在hexo博客中添加图片："><a href="#在hexo博客中添加图片：" class="headerlink" title="在hexo博客中添加图片："></a>在hexo博客中添加图片：</h3><p>参考文章：</p>
<ul>
<li><a href="https://hexo.io/zh-cn/docs/setup" target="_blank" rel="noopener">官方网站</a></li>
<li><a href="http://zwd596257180.gitee.io/blog/2019/04/15/hexo_manong_bog/" target="_blank" rel="noopener">码云+Hexo搭建个人博客+评论功能接入</a></li>
<li><a href="https://www.jianshu.com/p/3fe88ef479dd" target="_blank" rel="noopener">Hexo+Next 添加菜单分类页面</a></li>
<li><a href="https://blog.csdn.net/sinat_37781304/article/details/82729029" target="_blank" rel="noopener">hexo史上最全搭建教程</a></li>
<li><a href="https://www.simon96.online/2018/10/12/hexo-tutorial/" target="_blank" rel="noopener">最全Hexo博客搭建+主题优化+插件配置+常用操作+错误分析</a></li>
<li><a href="https://blog.csdn.net/nightmare_dimple/article/details/86661465" target="_blank" rel="noopener">利用Hexo将博客部署到GitPages和CodingPages</a></li>
</ul>

          
        
      
    </div>

    
    
    
      <footer class="post-footer">
          <div class="post-eof"></div>
        
      </footer>
  </div>
  
  
  
  </article>

    
      

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="http://yoursite.com/2019/11/14/2019/11/React context基本用法总结/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="淡退">
      <meta itemprop="description" content="欢迎你的到来！">
      <meta itemprop="image" content="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1565847089857&di=2bb546a711f57b819a4dbf3584c66392&imgtype=0&src=http%3A%2F%2Fhbimg.b0.upaiyun.com%2F458af12108c4da0f1cf4fe8e2713a458898e332b28196-jdjJ3j_fw658">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="淡退">
    </span>
      <header class="post-header">
        
          <i class="fa fa-thumb-tack"></i>
          <font color=7D26CD>置顶</font>
        

        
          <h1 class="post-title" itemprop="name headline">
              
              <a href="/2019/11/14/2019/11/React context基本用法总结/" class="post-title-link" itemprop="url">React context基本用法总结</a>
            
          </h1>
        

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              <span class="post-meta-item-text">发表于</span>

              
                
              

              <time title="创建时间：2019-11-14 23:10:17" itemprop="dateCreated datePublished" datetime="2019-11-14T23:10:17+08:00">2019-11-14</time>
            </span>
          
            

            
              <span class="post-meta-item">
                <span class="post-meta-item-icon">
                  <i class="fa fa-calendar-check-o"></i>
                </span>
                <span class="post-meta-item-text">更新于</span>
                <time title="修改时间：2019-12-08 21:06:33" itemprop="dateModified" datetime="2019-12-08T21:06:33+08:00">2019-12-08</time>
              </span>
            
          
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="fa fa-folder-o"></i>
              </span>
              <span class="post-meta-item-text">分类于</span>
              
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing"><a href="/categories/react/" itemprop="url" rel="index"><span itemprop="name">react</span></a></span>

                
                
              
            </span>
          

          

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
        <div class="post-gallery" itemscope itemtype="http://schema.org/ImageGallery">
            <div class="post-gallery-row">
              <img src="https://desk-fd.zol-img.com.cn/t_s1024x768c5/g5/M00/0C/02/ChMkJ13V9q6IOSp_AAPNPlvQOwwAAvV_QJYgfoAA81W947.jpg" itemprop="contentUrl">
            
          

          </div>
        </div>
          
            <a id="more"></a>
<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p><code>Context</code>被翻译为上下文，在编程领域，这是一个经常会接触到的概念，React中也有。</p>
<p>在<code>React</code>的官方文档中，<code>Context</code>被归类为高级部分<code>(Advanced)</code>，属于React的高级API，但官方并不建议在稳定版的App中使用<code>Contex</code>。</p>
<p>不过，这并非意味着我们不需要关注<code>Context</code>。事实上，很多优秀的<code>React</code>组件都通过<code>Context</code>来完成自己的功能，比如<code>react-redux的&lt;Provider /&gt;</code>，就是通过<code>Context</code>提供一个全局态的<code>store</code>，拖拽组件r<code>eact-dnd</code>，通过<code>Context</code>在组件中分发<code>DOM</code>的<code>Drag</code>和<code>Drop</code>事件，路由组件<code>react-router</code>通过<code>Context</code>管理路由状态等等。在React组件开发中，如果用好Context，可以让你的组件变得强大，而且灵活。</p>
<h3 id="初识React-Context"><a href="#初识React-Context" class="headerlink" title="初识React Context"></a>初识React Context</h3><p>当你不想在组件树中通过逐层传递<code>props</code>或者<code>state</code>的方式来传递数据时，可以使用Context来实现跨层级的组件数据传递。<br><img src="https://upload-images.jianshu.io/upload_images/1457831-b19e007758f57df7?imageMogr2/auto-orient/strip%7CimageView2/2/w/1200/format/webp" alt><br>使用<code>props</code>或者<code>state</code>传递数据，数据自顶下流。<br><img src="https://upload-images.jianshu.io/upload_images/1457831-1b8e3c5ce88f7758?imageMogr2/auto-orient/strip%7CimageView2/2/w/1200/format/webp" alt><br>使用Context，可以跨越组件进行数据传递。</p>
<h3 id="如何使用Context"><a href="#如何使用Context" class="headerlink" title="如何使用Context"></a>如何使用Context</h3><p>如果要Context发挥作用，需要用到两种组件，一个是<code>Context生产者(Provider)</code>，通常是一个父节点，另外是一个<code>Context的消费者(Consumer)</code>，通常是一个或者多个子节点。所以Context的使用基于生产者消费者模式。</p>
<p>对于父组件，也就是Context生产者，需要通过一个静态属性<code>childContextTypes</code>声明提供给子组件的Context对象的属性，并实现一个实例g<code>etChildContext</code>方法，返回一个代表Context的纯对象 (plain object) 。</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line">import React from &apos;react&apos;</span><br><span class="line">import PropTypes from &apos;prop-types&apos;</span><br><span class="line"></span><br><span class="line">class MiddleComponent extends React.Component &#123;</span><br><span class="line">  render () &#123;</span><br><span class="line">    return &lt;ChildComponent /&gt;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">class ParentComponent extends React.Component &#123;</span><br><span class="line">  // 声明Context对象属性</span><br><span class="line">  static childContextTypes = &#123;</span><br><span class="line">    propA: PropTypes.string,</span><br><span class="line">    methodA: PropTypes.func</span><br><span class="line">  &#125;</span><br><span class="line">  </span><br><span class="line">  // 返回Context对象，方法名是约定好的</span><br><span class="line">  getChildContext () &#123;</span><br><span class="line">    return &#123;</span><br><span class="line">      propA: &apos;propA&apos;,</span><br><span class="line">      methodA: () =&gt; &apos;methodA&apos;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">  </span><br><span class="line">  render () &#123;</span><br><span class="line">    return &lt;MiddleComponent /&gt;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>而对于Context的消费者，通过如下方式访问父组件提供的Context。</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line">import React from &apos;react&apos;</span><br><span class="line">import PropTypes from &apos;prop-types&apos;</span><br><span class="line"></span><br><span class="line">class ChildComponent extends React.Component &#123;</span><br><span class="line">  // 声明需要使用的Context属性</span><br><span class="line">  static contextTypes = &#123;</span><br><span class="line">    propA: PropTypes.string</span><br><span class="line">  &#125;</span><br><span class="line">  </span><br><span class="line">  render () &#123;</span><br><span class="line">    const &#123;</span><br><span class="line">      propA,</span><br><span class="line">      methodA</span><br><span class="line">    &#125; = this.context</span><br><span class="line">    </span><br><span class="line">    console.log(`context.propA = $&#123;propA&#125;`)  // context.propA = propA</span><br><span class="line">    console.log(`context.methodA = $&#123;methodA&#125;`)  // context.methodA = undefined</span><br><span class="line">    </span><br><span class="line">    return ...</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>子组件需要通过一个静态属性<code>contextTypes</code>声明后，才能访问父组件<code>Context</code>对象的属性，否则，即使属性名没写错，拿到的对象也是<code>undefined</code>。</p>
<p>对于无状态子组件(Stateless Component)，可以通过如下方式访问父组件的Context</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">import React from &apos;react&apos;</span><br><span class="line">import PropTypes from &apos;prop-types&apos;</span><br><span class="line"></span><br><span class="line">const ChildComponent = (props, context) =&gt; &#123;</span><br><span class="line">  const &#123;</span><br><span class="line">    propA</span><br><span class="line">  &#125; = context</span><br><span class="line">    </span><br><span class="line">  console.log(`context.propA = $&#123;propA&#125;`)  // context.propA = propA</span><br><span class="line">    </span><br><span class="line">  return ...</span><br><span class="line">&#125;</span><br><span class="line">  </span><br><span class="line">ChildComponent.contextProps = &#123;</span><br><span class="line">  propA: PropTypes.string    </span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>而在接下来的发行版本中，React对Context的API做了调整，更加明确了生产者消费者模式的使用方式。</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">import React from &apos;react&apos;;</span><br><span class="line">import ReactDOM from &apos;react-dom&apos;;</span><br><span class="line"></span><br><span class="line">const ThemeContext = React.createContext(&#123;</span><br><span class="line">  background: &apos;red&apos;,</span><br><span class="line">  color: &apos;white&apos;</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>

<p>通过静态方法<code>React.createContext()</code>创建一个Context对象，这个Context对象包含两个组件，<code>&lt;Provider /&gt;和&lt;Consumer /&gt;</code>。</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">class App extends React.Component &#123;</span><br><span class="line">  render () &#123;</span><br><span class="line">    return (</span><br><span class="line">      &lt;ThemeContext.Provider value=&#123;&#123;background: &apos;green&apos;, color: &apos;white&apos;&#125;&#125;&gt;</span><br><span class="line">        &lt;Header /&gt;</span><br><span class="line">      &lt;/ThemeContext.Provider&gt;</span><br><span class="line">    );</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><code>&lt;Provider /&gt;</code>的value相当于现在的<code>getChildContext()</code>。</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line">class Header extends React.Component &#123;</span><br><span class="line">  render () &#123;</span><br><span class="line">    return (</span><br><span class="line">      &lt;Title&gt;Hello React Context API&lt;/Title&gt;</span><br><span class="line">    );</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"> </span><br><span class="line">class Title extends React.Component &#123;</span><br><span class="line">  render () &#123;</span><br><span class="line">    return (</span><br><span class="line">      &lt;ThemeContext.Consumer&gt;</span><br><span class="line">        &#123;context =&gt; (</span><br><span class="line">          &lt;h1 style=&#123;&#123;background: context.background, color: context.color&#125;&#125;&gt;</span><br><span class="line">            &#123;this.props.children&#125;</span><br><span class="line">          &lt;/h1&gt;</span><br><span class="line">        )&#125;</span><br><span class="line">      &lt;/ThemeContext.Consumer&gt;</span><br><span class="line">    );</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><code>&lt;Consumer /&gt;</code>的children必须是一个函数，通过函数的参数获取<code>&lt;Provider /&gt;提供的Context</code>。<br>可见，Context的新API更加贴近React的风格。</p>
<h3 id="总结："><a href="#总结：" class="headerlink" title="总结："></a>总结：</h3><p>React的context就是一个全局变量，可以从根组件跨级别在React的组件中传递。React context 的API 有两个版本,React16.x 之前 的是老版本的 context，之后的是新版本的context。</p>
<h4 id="1-老版本的context"><a href="#1-老版本的context" class="headerlink" title="1.老版本的context"></a>1.老版本的context</h4><p><code>getChildContext</code>根组件中声明，一个函数，返回一个对象,就是context <code>childContextTyp</code>e根组件中声明,指定context的结构类 型，如不指定,会产生错误<br><code>contextTypes</code>子孙组件中声明，指定要接收的context的结构类型，可以只是context的一部分结构。contextTypes 没有定义，context将是一个空对象。<br><code>this.context</code> 在子孙组件中通过此来获取上下文</p>
<blockquote>
<p>(注:从React v15.5开始 ，React.PropTypes 助手函数已被弃用，可使用 prop-types 库 来定义contextTypes)</p>
</blockquote>
<p>举例如下：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br></pre></td><td class="code"><pre><span class="line">//根组件</span><br><span class="line">class MessageList extends React.Component &#123;</span><br><span class="line">  getChildContext() &#123;</span><br><span class="line">    return &#123;color: &quot;purple&quot;,text: &quot;item text&quot;&#125;;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  render() &#123;</span><br><span class="line">    const children = this.props.messages.map((message) =&gt;</span><br><span class="line">      &lt;Message text=&#123;message.text&#125; /&gt;</span><br><span class="line">    );</span><br><span class="line">    return &lt;div&gt;&#123;children&#125;&lt;/div&gt;;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">MessageList.childContextTypes = &#123;</span><br><span class="line">  color: React.PropTypes.string</span><br><span class="line">  text: React.PropTypes.string</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line">//中间组件</span><br><span class="line">class Message extends React.Component &#123;</span><br><span class="line">  render() &#123;</span><br><span class="line">    return (</span><br><span class="line">      &lt;div&gt;</span><br><span class="line">        &lt;MessageItem /&gt;</span><br><span class="line">        &lt;Button&gt;Delete&lt;/Button&gt;</span><br><span class="line">      &lt;/div&gt;</span><br><span class="line">    );</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">//孙组件(接收组件)</span><br><span class="line">class MessageItem extends React.Component &#123;</span><br><span class="line">  render() &#123;</span><br><span class="line">    return (</span><br><span class="line">      &lt;div&gt;</span><br><span class="line">        &#123;this.context.text&#125;</span><br><span class="line">      &lt;/div&gt;</span><br><span class="line">    );</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">MessageItem.contextTypes = &#123;</span><br><span class="line">  text: React.PropTypes.string</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line">class Button extends React.Component &#123;</span><br><span class="line">  render() &#123;</span><br><span class="line">    return (</span><br><span class="line">      &lt;button style=&#123;&#123;background: this.context.color&#125;&#125;&gt;</span><br><span class="line">        &#123;this.props.children&#125;</span><br><span class="line">      &lt;/button&gt;</span><br><span class="line">    );</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">Button.contextTypes = &#123;</span><br><span class="line">  color: React.PropTypes.string</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>

<h4 id="2-新版本的context"><a href="#2-新版本的context" class="headerlink" title="2.新版本的context"></a>2.新版本的context</h4><p>新版本的React context使用了Provider和Customer模式，和react-redux的模式非常像。在顶层的Provider中传入value，<br>在子孙级的Consumer中获取该值，并且能够传递函数，用来修改context，如下代码所示：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br></pre></td><td class="code"><pre><span class="line">//创建Context组件</span><br><span class="line">const ThemeContext = React.createContext(&#123;</span><br><span class="line">  theme: &apos;dark&apos;,</span><br><span class="line">  toggle: () =&gt; &#123;&#125;, //向上下文设定一个回调方法</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">//运行APP</span><br><span class="line">class App extends React.Component &#123;</span><br><span class="line">  constructor(props) &#123;</span><br><span class="line">    super(props);</span><br><span class="line"></span><br><span class="line">    this.toggle = () =&gt; &#123; //设定toggle方法，会作为context参数传递</span><br><span class="line">      this.setState(state =&gt; (&#123;</span><br><span class="line">        theme:</span><br><span class="line">          state.theme === themes.dark</span><br><span class="line">            ? themes.light</span><br><span class="line">            : themes.dark,</span><br><span class="line">      &#125;));</span><br><span class="line">    &#125;;</span><br><span class="line"></span><br><span class="line">    this.state = &#123;</span><br><span class="line">      theme: themes.light,</span><br><span class="line">      toggle: this.toggle,</span><br><span class="line">    &#125;;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  render() &#123;</span><br><span class="line">    return (</span><br><span class="line">      &lt;ThemeContext.Provider value=&#123;this.state&#125;&gt; //state包含了toggle方法</span><br><span class="line">        &lt;Content /&gt;</span><br><span class="line">      &lt;/ThemeContext.Provider&gt;</span><br><span class="line">    );</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">//中间组件</span><br><span class="line">function Content() &#123;</span><br><span class="line">  return (</span><br><span class="line">    &lt;div&gt;</span><br><span class="line">      &lt;Button /&gt;</span><br><span class="line">    &lt;/div&gt;</span><br><span class="line">  );</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">//接收组件</span><br><span class="line">function Button() &#123;</span><br><span class="line">  return (</span><br><span class="line">    &lt;ThemeContext.Consumer&gt;</span><br><span class="line">      &#123;(&#123;theme, toggle&#125;) =&gt; (</span><br><span class="line">        &lt;button</span><br><span class="line">          onClick=&#123;toggle&#125; //调用回调</span><br><span class="line">          style=&#123;&#123;backgroundColor: theme&#125;&#125;&gt;</span><br><span class="line">          Toggle Theme</span><br><span class="line">        &lt;/button&gt;</span><br><span class="line">      )&#125;</span><br><span class="line">    &lt;/ThemeContext.Consumer&gt;</span><br><span class="line">  );</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>详细用法可以参考官方文档：<a href="https://react.docschina.org/docs/context.html#reactcreatecontext" target="_blank" rel="noopener">https://react.docschina.org/docs/context.html#reactcreatecontext</a></p>
<h4 id="3-context在如下的生命周期钩子中可以使用"><a href="#3-context在如下的生命周期钩子中可以使用" class="headerlink" title="3. context在如下的生命周期钩子中可以使用"></a>3. context在如下的生命周期钩子中可以使用</h4><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">constructor(props, context)</span><br><span class="line">componentWillReceiveProps(nextProps, nextContext)</span><br><span class="line">shouldComponentUpdate(nextProps, nextState, nextContext)</span><br><span class="line">componentWillUpdate(nextProps, nextState, nextContext)</span><br><span class="line">componentDidUpdate(prevProps, prevState, prevContext)</span><br></pre></td></tr></table></figure>

<h4 id="4-在无状态组件中可以通过参数传入"><a href="#4-在无状态组件中可以通过参数传入" class="headerlink" title="4. 在无状态组件中可以通过参数传入"></a>4. 在无状态组件中可以通过参数传入</h4><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">function D(props, context) &#123;</span><br><span class="line">  return (</span><br><span class="line">    &lt;div&gt;&#123;this.context.user.name&#125;&lt;/div&gt;</span><br><span class="line">  );</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">D.contextTypes = &#123;</span><br><span class="line">  user: React.PropTypes.object.isRequired</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h4 id="5-React-context的局限性"><a href="#5-React-context的局限性" class="headerlink" title="5. React context的局限性"></a>5. React context的局限性</h4><ol>
<li>在组件树中，如果中间某一个组件 <code>ShouldComponentUpdate returning false</code> 了，会阻碍 context 的正常传值，导致子组件无法获取更新。</li>
<li>组件本身 <code>extends React.PureComponent</code> 也会阻碍 context 的更新。</li>
</ol>
<blockquote>
<p>注意点：</p>
<ol>
<li>Context 应该是唯一不可变的. </li>
<li>组件只在初始化的时候去获取 Context</li>
</ol>
</blockquote>
<p>参考: </p>
<ol>
<li><a href="https://www.tuicool.com/articles/nUryimf" target="_blank" rel="noopener">https://www.tuicool.com/articles/nUryimf</a></li>
<li><a href="https://segmentfault.com/a/1190000012575622" target="_blank" rel="noopener">https://segmentfault.com/a/1190000012575622</a></li>
<li><a href="https://www.jianshu.com/p/eba2b76b290b" target="_blank" rel="noopener">https://www.jianshu.com/p/eba2b76b290b</a></li>
</ol>

          
        
      
    </div>

    
    
    
      <footer class="post-footer">
          <div class="post-eof"></div>
        
      </footer>
  </div>
  
  
  
  </article>

    
      

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="http://yoursite.com/2019/11/13/2019/11/ES6 Promise原生实现 、 Generator深入学习/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="淡退">
      <meta itemprop="description" content="欢迎你的到来！">
      <meta itemprop="image" content="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1565847089857&di=2bb546a711f57b819a4dbf3584c66392&imgtype=0&src=http%3A%2F%2Fhbimg.b0.upaiyun.com%2F458af12108c4da0f1cf4fe8e2713a458898e332b28196-jdjJ3j_fw658">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="淡退">
    </span>
      <header class="post-header">
        
          <i class="fa fa-thumb-tack"></i>
          <font color=7D26CD>置顶</font>
        

        
          <h1 class="post-title" itemprop="name headline">
              
              <a href="/2019/11/13/2019/11/ES6 Promise原生实现 、 Generator深入学习/" class="post-title-link" itemprop="url">ES6 Promise原生实现 、 Generator深入学习</a>
            
          </h1>
        

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              <span class="post-meta-item-text">发表于</span>

              
                
              

              <time title="创建时间：2019-11-13 23:10:17" itemprop="dateCreated datePublished" datetime="2019-11-13T23:10:17+08:00">2019-11-13</time>
            </span>
          
            

            
              <span class="post-meta-item">
                <span class="post-meta-item-icon">
                  <i class="fa fa-calendar-check-o"></i>
                </span>
                <span class="post-meta-item-text">更新于</span>
                <time title="修改时间：2019-11-24 17:30:02" itemprop="dateModified" datetime="2019-11-24T17:30:02+08:00">2019-11-24</time>
              </span>
            
          
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="fa fa-folder-o"></i>
              </span>
              <span class="post-meta-item-text">分类于</span>
              
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing"><a href="/categories/js/" itemprop="url" rel="index"><span itemprop="name">js</span></a></span>

                
                
              
            </span>
          

          

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
        <div class="post-gallery" itemscope itemtype="http://schema.org/ImageGallery">
            <div class="post-gallery-row">
              <img src="https://desk-fd.zol-img.com.cn/t_s1024x768c5/g5/M00/0C/02/ChMkJ13V9q6IOSp_AAPNPlvQOwwAAvV_QJYgfoAA81W947.jpg" itemprop="contentUrl">
            
          

          </div>
        </div>
          <h2 id="11-13-ES6-Promise原生实现-、-Generator深入学习"><a href="#11-13-ES6-Promise原生实现-、-Generator深入学习" class="headerlink" title="11-13 ES6 Promise原生实现 、 Generator深入学习"></a>11-13 ES6 Promise原生实现 、 Generator深入学习</h2><h3 id="了解"><a href="#了解" class="headerlink" title="了解"></a>了解</h3><ol>
<li><p>Promise 的局限性。</p>
</li>
<li><p>原生实现 、其一些细节。</p>
</li>
<li><p>Generator 自执行函数的实现。</p>
          <!--noindex-->
          
            <div class="post-button text-center">
              <a class="btn" href="/2019/11/13/2019/11/ES6 Promise原生实现 、 Generator深入学习/#more" rel="contents">
                阅读全文 &raquo;
              </a>
            </div>
          
          <!--/noindex-->
        
      
    </div>

    
    
    
      <footer class="post-footer">
          <div class="post-eof"></div>
        
      </footer>
  </div>
  
  
  
  </article>

    
  </section>

  
  <nav class="pagination">
    <span class="page-number current">1</span><a class="page-number" href="/page/2/">2</a><a class="extend next" rel="next" href="/page/2/"><i class="fa fa-angle-right" aria-label="下一页"></i></a>
  </nav>


          </div>
          

        </div>
          
  
  <div class="sidebar-toggle">
    <div class="sidebar-toggle-line-wrap">
      <span class="sidebar-toggle-line sidebar-toggle-line-first"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-middle"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-last"></span>
    </div>
  </div>

  <aside id="sidebar" class="sidebar">
    <div class="sidebar-inner">

      <div class="site-overview-wrap sidebar-panel sidebar-panel-active">
        <div class="site-overview">

          <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
    <img class="site-author-image" itemprop="image"
      src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1565847089857&di=2bb546a711f57b819a4dbf3584c66392&imgtype=0&src=http%3A%2F%2Fhbimg.b0.upaiyun.com%2F458af12108c4da0f1cf4fe8e2713a458898e332b28196-jdjJ3j_fw658"
      alt="淡退">
  <p class="site-author-name" itemprop="name">淡退</p>
  <div class="site-description motion-element" itemprop="description">欢迎你的到来！</div>
</div>
  <nav class="site-state motion-element">
      <div class="site-state-item site-state-posts">
        
          <a href="/archives/">
        
          <span class="site-state-item-count">14</span>
          <span class="site-state-item-name">日志</span>
        </a>
      </div>
    
      
      
      <div class="site-state-item site-state-categories">
        
          
            <a href="/categories/">
          
        
        
        
          
        
          
        
          
        
          
        
          
        
        <span class="site-state-item-count">5</span>
        <span class="site-state-item-name">分类</span>
        </a>
      </div>
    
      
      
      <div class="site-state-item site-state-tags">
        
          
            <a href="/tags/">
          
        
        
        
          
        
          
        
          
        
          
        
          
        
          
        
          
        
          
        
          
        
          
        
        <span class="site-state-item-count">10</span>
        <span class="site-state-item-name">标签</span>
        </a>
      </div>
    
  </nav>



        </div>
      </div>

    </div>
  </aside>
  <div id="sidebar-dimmer"></div>


      </div>
    </main>

    <footer id="footer" class="footer">
      <div class="footer-inner">
        <div class="copyright">&copy; <span itemprop="copyrightYear">2020</span>
  <span class="with-love" id="animate">
    <!--<i class="fa fa-user"></i>-->
    <i class="fa fa-heart"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">淡退</span>
</div>
<!--
  <div class="powered-by">由 <a href="https://hexo.io" class="theme-link" rel="noopener" target="_blank">Hexo</a> 强力驱动 v3.9.0</div>
  <span class="post-meta-divider">|</span>
  <div class="theme-info">主题 – <a href="https://theme-next.org" class="theme-link" rel="noopener" target="_blank">NexT.Gemini</a> v7.3.0</div>
-->
        








        
      </div>
    </footer>
      <div class="back-to-top">
        <i class="fa fa-arrow-up"></i>
      </div>

    

  </div>

  
  <script src="/lib/jquery/index.js?v=3.4.1"></script>
  <script src="/lib/velocity/velocity.min.js?v=1.2.1"></script>
  <script src="/lib/velocity/velocity.ui.min.js?v=1.2.1"></script>

<script src="/js/utils.js?v=7.3.0"></script>
  <script src="/js/motion.js?v=7.3.0"></script>


  <script src="/js/affix.js?v=7.3.0"></script>
  <script src="/js/schemes/pisces.js?v=7.3.0"></script>



<script src="/js/next-boot.js?v=7.3.0"></script>




  















  <script src="/js/local-search.js?v=7.3.0"></script>














  

  

  


  
  <script type="text/javascript" src="//cdn.bootcss.com/canvas-nest.js/1.0.0/canvas-nest.min.js"></script>
</body>
</html>
